From 626f08162b07a49e8683bfb04a71ac02faa9b12d Mon Sep 17 00:00:00 2001 From: Nikita Kostovsky Date: Sat, 25 Jan 2025 18:44:39 +0100 Subject: add inno-maker ov9281 stream. cmake config failed --- CMakeLists.txt | 17 ++++++++------- main.cpp | 43 +++++++++++++++++++++++++----------- src/camera/icamera.h | 40 ++++++++++++++++++++++++++++++++++ src/camera/innomakerov9281.cpp | 49 +++++++++++++++++++++++++++++++++++++++++- src/camera/innomakerov9281.h | 25 ++++++++++++++------- src/camera/ov9281.cpp | 1 + src/camera/ov9281.h | 15 ++++++++----- 7 files changed, 155 insertions(+), 35 deletions(-) create mode 100644 src/camera/icamera.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e08791..4b0cabb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,17 +1,17 @@ -cmake_minimum_required(VERSION 3.16) -set(CMAKE_CXX_STANDARD 23) - cmake_minimum_required(VERSION 3.18) -include_guard(GLOBAL) -set(CMAKE_INCLUDE_CURRENT_DIR ON) -set(CMAKE_AUTOMOC ON) -set(CMAKE_AUTORCC OFF) +set(CMAKE_CXX_STANDARD 23) +include_guard(GLOBAL) set(CMAKE_SYSTEM_NAME Linux) set(CMAKE_SYSTEM_PROCESSOR arm) -set(TARGET_SYSROOT /home/nikita/rpi/rpi-sysroot) +set(CMAKE_INCLUDE_CURRENT_DIR ON) +# set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC OFF) + +# set(TARGET_SYSROOT /home/nikita/rpi/rpi-sysroot) +set(TARGET_SYSROOT /home/nikita/rpi/rpi_zero-sysroot) set(CMAKE_SYSROOT ${TARGET_SYSROOT}) set(CMAKE_LIBRARY_PATH ${CMAKE_SYSROOT}/usr/lib/aarch64-linux-gnu) @@ -128,6 +128,7 @@ qt_add_executable(apporpheus src/image.h src/image.cpp src/laser.h src/laser.cpp src/camera/innomakerov9281.h src/camera/innomakerov9281.cpp + src/camera/icamera.h ) target_link_libraries(app${PROJECT_NAME} PRIVATE diff --git a/main.cpp b/main.cpp index 19108d0..e8de499 100644 --- a/main.cpp +++ b/main.cpp @@ -17,6 +17,7 @@ #include "httpservice.h" #include "imagealgos.h" #include "laser.h" +#include "macro.h" #include "pigpio.h" #include "printerclient.h" #include "profile.h" @@ -91,6 +92,7 @@ auto printPixels = [](const auto& pixels) { void onNewImage( std::shared_ptr image) { + std::cout << __func__ << std::endl << std::flush; if (!image) { qDebug() << __func__ << "no image"; return; @@ -126,26 +128,29 @@ int main(int argc, char* argv[]) QCoreApplication app(argc, argv); #ifdef INNO_MAKER - { + if (false) { std::cout << std::boolalpha; InnoMakerOV9281 innoMakerCam; qDebug() << "init:" << innoMakerCam.init(); qDebug() << "set exposure:" << innoMakerCam.setExposureTimeMs(3000); qDebug() << "set gain:" << innoMakerCam.setGain(3000); - Image buf; + innoMakerCam.startStream(); + QThread::sleep(3); + qDebug() << "should be stopped"; + // Image buf; - for (size_t i = 0; i < 1000; ++i) { - if (!innoMakerCam.getImage(buf)) { - break; - } + // for (size_t i = 0; i < 1000; ++i) { + // if (!innoMakerCam.getImage(buf)) { + // break; + // } - buf.rotate(); - auto pixels = buf.pixels(); - } + // buf.rotate(); + // auto pixels = buf.pixels(); + // } } - qDebug() << "ok"; - exit(EXIT_SUCCESS); + // qDebug() << "ok"; + // exit(EXIT_SUCCESS); #endif // if (false) @@ -336,29 +341,39 @@ int main(int argc, char* argv[]) qDebug() << "msecs before camera:" << t.elapsed(); // FIXME: don't use one var for everything int ret; +#ifndef INNO_MAKER std::unique_ptr cm = std::make_unique(); cm->start(); - +#endif // const auto cameras = cm->cameras(); - const auto cameras = OV9281::search(cm); + // const auto cameras = OV9281::search(cm); + const auto cameras = InnoMakerOV9281::search(); + // const auto cameras = if (cameras.empty()) { std::cerr << "No cameras were identified on the system." << std::endl; +#ifndef INNO_MAKER cm->stop(); +#endif return EXIT_FAILURE; } auto camera = cameras.at(0); +#ifndef INNO_MAKER camera->printControls(); +#endif + std::cout << "connect everything" << std::endl; camera->newPixels.connect(&onNewPixels); camera->newImage.connect(&onNewImage); if (!camera->startStream()) { +#ifndef INNO_MAKER cm->stop(); +#endif return EXIT_FAILURE; } @@ -634,7 +649,9 @@ int main(int argc, char* argv[]) // allocator.reset(); // camera->release(); // camera.reset(); +#ifndef INNO_MAKER cm->stop(); +#endif return result; } diff --git a/src/camera/icamera.h b/src/camera/icamera.h new file mode 100644 index 0000000..4245a68 --- /dev/null +++ b/src/camera/icamera.h @@ -0,0 +1,40 @@ +#pragma once + +#ifdef emit +#define emit_backup emit +#undef emit +#endif + +#ifdef slots +#define slots_backup slots +#undef slots +#endif + +#include + +#ifdef emit_backup +#define emit emit_backup +#endif + +#ifdef slots_backup +#define slots slots_backup +#endif + +#include "image.h" + +// class ICamera +// { +// public: +// virtual bool setExposureTimeMs(int value) = 0; +// virtual bool setGain(int value) = 0; +// }; + +class ICamera +{ +public: + libcamera::Signal> newPixels; + libcamera::Signal> newImage; + +public: + virtual bool startStream() = 0; +}; diff --git a/src/camera/innomakerov9281.cpp b/src/camera/innomakerov9281.cpp index 6d7aa4a..a2d3136 100644 --- a/src/camera/innomakerov9281.cpp +++ b/src/camera/innomakerov9281.cpp @@ -9,6 +9,8 @@ #include #include +#include + #include "constants.h" // #include "rotaryencoder.h" @@ -25,12 +27,15 @@ extern uint64_t corr_elapsed_ns; extern uint64_t max_elapsed_ns; extern uint64_t value_elapsed_ns; -constexpr char videoDevice[] = "/dev/video0"; +// constexpr char videoDevice[] = "/dev/video0"; InnoMakerOV9281::InnoMakerOV9281() {} InnoMakerOV9281::~InnoMakerOV9281() { + m_streamThread.request_stop(); + m_streamThread.join(); + int ret{-1}; for (int i = 0; i < BUFFER_COUNT; ++i) { @@ -55,6 +60,48 @@ InnoMakerOV9281::~InnoMakerOV9281() // std::cout << __func__ << ": success" << std::endl; } +std::vector > InnoMakerOV9281::search() +{ + // return only one camera for now + std::cout << std::boolalpha; + auto cam = std::make_shared(); + + if (!cam->init()) + return {}; + + if (!cam->setExposureTimeMs(3000)) + return {}; + + if (!cam->setGain(3000)) + return {}; + + return {cam}; +} + +bool InnoMakerOV9281::startStream() +{ + m_streamThread = std::jthread{[&](std::stop_token stopToken) { + std::cout << "InnoMakerOV9281: start stream" << std::endl; + + while (!stopToken.stop_requested()) { + std::shared_ptr image = std::make_shared(); + getImage(*image); +// FIXME: backup emit value +#ifdef emit +#undef emit + std::cout << "emit new image" << std::endl << std::flush; + newImage.emit(image); + auto pixels = image->pixels(); + newPixels.emit(pixels); + } +#define emit +#endif + std::cout << "InnoMakerOV9281: stream interruption requested" << std::endl; + }}; + + return true; +} + bool InnoMakerOV9281::init() { if (!openCam()) diff --git a/src/camera/innomakerov9281.h b/src/camera/innomakerov9281.h index 51485cb..2c1fb7c 100644 --- a/src/camera/innomakerov9281.h +++ b/src/camera/innomakerov9281.h @@ -2,18 +2,17 @@ #include +#include + #include "constants.h" #include "image.h" -class ICamera -{ -public: - virtual bool setExposureTimeMs(int value) = 0; - virtual bool setGain(int value) = 0; -}; +#include "icamera.h" class InnoMakerOV9281 : public ICamera { + constexpr static char videoDevice[] = "/dev/video0"; + public: using buffer_t = std::array; @@ -22,13 +21,22 @@ public: ~InnoMakerOV9281(); public: + static std::vector> search(); + +public: + bool startStream(); + bool init(); - bool setExposureTimeMs(int value) override; - bool setGain(int value) override; + bool setExposureTimeMs(int value); + bool setGain(int value); bool getImage(Image &image); +public: + libcamera::Signal> newPixels; + libcamera::Signal> newImage; + private: bool setCamParam(unsigned int v4l2controlId, int value); bool openCam(); @@ -40,4 +48,5 @@ private: static constexpr uint8_t BUFFER_COUNT{3}; uint8_t *video_buffer_ptr[BUFFER_COUNT]; // buffer_t m_buf; + std::jthread m_streamThread; }; diff --git a/src/camera/ov9281.cpp b/src/camera/ov9281.cpp index 48f445f..1a324e4 100644 --- a/src/camera/ov9281.cpp +++ b/src/camera/ov9281.cpp @@ -209,6 +209,7 @@ void OV9281::onRequestCompleted(libcamera::Request *completed_request) img->rotate(); auto pixels = img->pixels(); +// FIXME: backup emit value #ifdef emit #undef emit if (!pixels) { diff --git a/src/camera/ov9281.h b/src/camera/ov9281.h index 1f2011a..83a86ac 100644 --- a/src/camera/ov9281.h +++ b/src/camera/ov9281.h @@ -4,9 +4,12 @@ #include #include -#include #include +#include + +#include "icamera.h" + namespace libcamera { class Camera; class CameraConfiguration; @@ -18,8 +21,10 @@ class Request; class Image; class Pixels; -class OV9281 +class OV9281 : public QObject, public ICamera { + Q_OBJECT + public: ~OV9281(); @@ -29,15 +34,15 @@ public: // public functions public: - bool startStream(); + bool startStream() override; void printControls(); // signals public: // TODO: image->pixels in separate thread // TODO: respect sender/receiver threads - libcamera::Signal> newPixels; - libcamera::Signal> newImage; + // libcamera::Signal> newPixels; + // libcamera::Signal> newImage; private: explicit OV9281(const std::shared_ptr &camera); -- cgit v1.2.3-70-g09d2