|
@@ -1,7 +1,9 @@
|
|
|
#include "augment_renderer.h"
|
|
#include "augment_renderer.h"
|
|
|
#include "config.h"
|
|
#include "config.h"
|
|
|
|
|
+#include "frame_buffer_helper.hpp"
|
|
|
#include "stereo_camera.hpp"
|
|
#include "stereo_camera.hpp"
|
|
|
#include "texture_renderer.h"
|
|
#include "texture_renderer.h"
|
|
|
|
|
+#include "video_encoder.h"
|
|
|
|
|
|
|
|
#include <imgui.h>
|
|
#include <imgui.h>
|
|
|
#include <imgui_impl_glfw.h>
|
|
#include <imgui_impl_glfw.h>
|
|
@@ -10,12 +12,19 @@
|
|
|
#include <glad/gl.h>
|
|
#include <glad/gl.h>
|
|
|
#include <GLFW/glfw3.h>
|
|
#include <GLFW/glfw3.h>
|
|
|
|
|
|
|
|
|
|
+#include <fmt/chrono.h>
|
|
|
|
|
+#include <fmt/format.h>
|
|
|
#include <spdlog/spdlog.h>
|
|
#include <spdlog/spdlog.h>
|
|
|
|
|
|
|
|
#include <cassert>
|
|
#include <cassert>
|
|
|
|
|
+#include <cstdlib>
|
|
|
|
|
+
|
|
|
|
|
+CUcontext cuda_ctx;
|
|
|
|
|
|
|
|
int main() {
|
|
int main() {
|
|
|
|
|
|
|
|
|
|
+ spdlog::set_level(spdlog::level::trace);
|
|
|
|
|
+
|
|
|
// setup glfw and main window
|
|
// setup glfw and main window
|
|
|
glfwSetErrorCallback([](int error, const char *desc) {
|
|
glfwSetErrorCallback([](int error, const char *desc) {
|
|
|
SPDLOG_ERROR("GLFW error: code = {}, description = {}", error, desc);
|
|
SPDLOG_ERROR("GLFW error: code = {}, description = {}", error, desc);
|
|
@@ -57,16 +66,32 @@ int main() {
|
|
|
ImGui_ImplGlfw_InitForOpenGL(main_window, true);
|
|
ImGui_ImplGlfw_InitForOpenGL(main_window, true);
|
|
|
ImGui_ImplOpenGL3_Init();
|
|
ImGui_ImplOpenGL3_Init();
|
|
|
|
|
|
|
|
|
|
+ // setup cuda context
|
|
|
|
|
+ cuInit(0);
|
|
|
|
|
+ create_cuda_context(&cuda_ctx);
|
|
|
|
|
+
|
|
|
// working staffs
|
|
// working staffs
|
|
|
stereo_camera camera;
|
|
stereo_camera camera;
|
|
|
texture_renderer tex_renderer;
|
|
texture_renderer tex_renderer;
|
|
|
|
|
|
|
|
|
|
+ frame_buffer_helper fbo_helper;
|
|
|
|
|
+ fbo_helper.initialize(image_width * 2, image_height);
|
|
|
|
|
+
|
|
|
|
|
+ video_encoder encoder;
|
|
|
|
|
+ encoder.initialize();
|
|
|
|
|
+
|
|
|
augment_renderer left_ar, right_ar;
|
|
augment_renderer left_ar, right_ar;
|
|
|
left_ar.initialize(&tex_renderer);
|
|
left_ar.initialize(&tex_renderer);
|
|
|
right_ar.initialize(&tex_renderer);
|
|
right_ar.initialize(&tex_renderer);
|
|
|
left_ar.set_background(&camera.left_rgb_image);
|
|
left_ar.set_background(&camera.left_rgb_image);
|
|
|
right_ar.set_background(&camera.right_rgb_image);
|
|
right_ar.set_background(&camera.right_rgb_image);
|
|
|
|
|
|
|
|
|
|
+ int camera_fps = default_camera_fps;
|
|
|
|
|
+ float exposure_time_ms = default_camera_exposure_time_ms;
|
|
|
|
|
+ float analog_gain = default_camera_analog_gain;
|
|
|
|
|
+
|
|
|
|
|
+ FILE *video_save_file = nullptr;
|
|
|
|
|
+
|
|
|
// main loop
|
|
// main loop
|
|
|
while (!glfwWindowShouldClose(main_window)) {
|
|
while (!glfwWindowShouldClose(main_window)) {
|
|
|
|
|
|
|
@@ -80,12 +105,14 @@ int main() {
|
|
|
|
|
|
|
|
if (ImGui::Begin("Remote AR Control")) {
|
|
if (ImGui::Begin("Remote AR Control")) {
|
|
|
|
|
|
|
|
|
|
+ // extra actions to make consistency
|
|
|
|
|
+ if (!camera.is_capturing() && encoder.is_encoding()) {
|
|
|
|
|
+ encoder.stop_encode();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// camera control
|
|
// camera control
|
|
|
if (ImGui::CollapsingHeader("Camera")) {
|
|
if (ImGui::CollapsingHeader("Camera")) {
|
|
|
-
|
|
|
|
|
- static int trigger_interval_ms = default_camera_capture_interval_ms;
|
|
|
|
|
- static float exposure_time_ms = default_camera_exposure_time_ms;
|
|
|
|
|
- static float analog_gain = default_camera_analog_gain;
|
|
|
|
|
|
|
+ ImGui::PushID("Camera");
|
|
|
|
|
|
|
|
// camera actions
|
|
// camera actions
|
|
|
ImGui::SeparatorText("Actions");
|
|
ImGui::SeparatorText("Actions");
|
|
@@ -100,7 +127,7 @@ int main() {
|
|
|
ImGui::SameLine();
|
|
ImGui::SameLine();
|
|
|
if (!camera.is_capturing()) {
|
|
if (!camera.is_capturing()) {
|
|
|
if (ImGui::Button("Start")) {
|
|
if (ImGui::Button("Start")) {
|
|
|
- camera.start_capture(1000 * exposure_time_ms, analog_gain, trigger_interval_ms);
|
|
|
|
|
|
|
+ camera.start_capture(1000 * exposure_time_ms, analog_gain, camera_fps);
|
|
|
}
|
|
}
|
|
|
} else {
|
|
} else {
|
|
|
if (ImGui::Button("Stop")) {
|
|
if (ImGui::Button("Stop")) {
|
|
@@ -119,9 +146,9 @@ int main() {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
ImGui::PushItemWidth(200);
|
|
ImGui::PushItemWidth(200);
|
|
|
- ImGui::SliderInt("Trigger Interval (ms)", &trigger_interval_ms, 17, 100);
|
|
|
|
|
|
|
+ ImGui::SliderInt("Frame Rate (fps)", &camera_fps, 1, 60);
|
|
|
ImGui::DragFloat("Exposure Time (ms)", &exposure_time_ms,
|
|
ImGui::DragFloat("Exposure Time (ms)", &exposure_time_ms,
|
|
|
- 0.1, 1, (float) trigger_interval_ms, "%.1f");
|
|
|
|
|
|
|
+ 0.1, 1, 1e3f / (float) camera_fps, "%.1f");
|
|
|
ImGui::DragFloat("Analog Gain (dB)", &analog_gain, 0.1, 0, 24, "%.1f");
|
|
ImGui::DragFloat("Analog Gain (dB)", &analog_gain, 0.1, 0, 24, "%.1f");
|
|
|
ImGui::PopItemWidth();
|
|
ImGui::PopItemWidth();
|
|
|
|
|
|
|
@@ -129,6 +156,34 @@ int main() {
|
|
|
ImGui::EndDisabled();
|
|
ImGui::EndDisabled();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
+
|
|
|
|
|
+ ImGui::PopID();
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ // video streamer control
|
|
|
|
|
+ if (camera.is_capturing() && ImGui::CollapsingHeader("Video Streamer")) {
|
|
|
|
|
+ ImGui::PushID("Streamer");
|
|
|
|
|
+
|
|
|
|
|
+ ImGui::SeparatorText("Actions");
|
|
|
|
|
+ if (!encoder.is_encoding()) {
|
|
|
|
|
+ if (ImGui::Button("Start")) {
|
|
|
|
|
+ // create save file
|
|
|
|
|
+ auto file_name = fmt::format("record_{:%Y_%m_%d_%H_%M_%S}.hevc",
|
|
|
|
|
+ std::chrono::system_clock::now());
|
|
|
|
|
+ video_save_file = fopen(file_name.c_str(), "wb");
|
|
|
|
|
+
|
|
|
|
|
+ encoder.start_encode(fbo_helper.tex_width, fbo_helper.tex_height, camera_fps);
|
|
|
|
|
+ SPDLOG_INFO("Video streamer started.");
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (ImGui::Button("Close")) {
|
|
|
|
|
+ encoder.stop_encode();
|
|
|
|
|
+ fclose(video_save_file);
|
|
|
|
|
+ SPDLOG_INFO("Video streamer stopped.");
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ ImGui::PopID();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
}
|
|
}
|
|
@@ -136,6 +191,7 @@ int main() {
|
|
|
ImGui::Render();
|
|
ImGui::Render();
|
|
|
|
|
|
|
|
int frame_width, frame_height;
|
|
int frame_width, frame_height;
|
|
|
|
|
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
|
|
|
glfwGetFramebufferSize(main_window, &frame_width, &frame_height);
|
|
glfwGetFramebufferSize(main_window, &frame_width, &frame_height);
|
|
|
glViewport(0, 0, frame_width, frame_height);
|
|
glViewport(0, 0, frame_width, frame_height);
|
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
@@ -144,19 +200,40 @@ int main() {
|
|
|
camera.retrieve_raw_images();
|
|
camera.retrieve_raw_images();
|
|
|
camera.debayer_images();
|
|
camera.debayer_images();
|
|
|
|
|
|
|
|
- augment_renderer::render_config config{-1, 1, 2, -2};
|
|
|
|
|
- left_ar.render(&config);
|
|
|
|
|
|
|
+ // draw frame in the screen
|
|
|
|
|
+ left_ar.render({-1, 1, 2, -2});
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
|
ImGui_ImplOpenGL3_RenderDrawData(ImGui::GetDrawData());
|
|
|
glfwSwapBuffers(main_window);
|
|
glfwSwapBuffers(main_window);
|
|
|
|
|
|
|
|
|
|
+ if (encoder.is_encoding()) {
|
|
|
|
|
+ // draw frame for streaming
|
|
|
|
|
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, fbo_helper.fbo);
|
|
|
|
|
+ glViewport(0, 0, fbo_helper.tex_width, fbo_helper.tex_height);
|
|
|
|
|
+ left_ar.render({-1, -1, 1, 2});
|
|
|
|
|
+ right_ar.render({0, -1, 1, 2});
|
|
|
|
|
+
|
|
|
|
|
+ // encode frame
|
|
|
|
|
+ fbo_helper.download_pixels();
|
|
|
|
|
+ void *frame_data;
|
|
|
|
|
+ size_t frame_length;
|
|
|
|
|
+ encoder.encode_frame(fbo_helper.pbo_res, &frame_data, &frame_length);
|
|
|
|
|
+
|
|
|
|
|
+ // save encoded frame
|
|
|
|
|
+ fwrite(frame_data, frame_length, 1, video_save_file);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (camera.is_capturing()) {
|
|
if (camera.is_capturing()) {
|
|
|
glFlush();
|
|
glFlush();
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// cleanup
|
|
// cleanup
|
|
|
|
|
+ std::atexit([]() {
|
|
|
|
|
+ cuCtxDestroy(cuda_ctx);
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
ImGui_ImplOpenGL3_Shutdown();
|
|
ImGui_ImplOpenGL3_Shutdown();
|
|
|
ImGui_ImplGlfw_Shutdown();
|
|
ImGui_ImplGlfw_Shutdown();
|
|
|
ImGui::DestroyContext();
|
|
ImGui::DestroyContext();
|