diff options
| author | Nikita Kostovsky <nikita@kostovsky.me> | 2025-02-28 23:28:12 +0100 |
|---|---|---|
| committer | Nikita Kostovsky <nikita@kostovsky.me> | 2025-02-28 23:28:12 +0100 |
| commit | fe81095bf011786ee5303549abc8debb22cddcf8 (patch) | |
| tree | c0b77e9d1b6a6682cb0fe7a3bc03617660377387 /src | |
| parent | a554cb955012adc51ab0d82af32206fd38a88da8 (diff) | |
got 480 fps with pixels calc
Diffstat (limited to 'src')
| -rw-r--r-- | src/camera/icamera.h | 3 | ||||
| -rw-r--r-- | src/camera/ov9281.cpp | 2 | ||||
| -rw-r--r-- | src/camera/veyeimx287m.cpp | 529 | ||||
| -rw-r--r-- | src/camera/veyeimx287m.h | 73 | ||||
| -rw-r--r-- | src/image.cpp | 42 | ||||
| -rw-r--r-- | src/image.h | 11 | ||||
| -rw-r--r-- | src/main.cpp | 93 |
7 files changed, 694 insertions, 59 deletions
diff --git a/src/camera/icamera.h b/src/camera/icamera.h index 11919bb..39d358f 100644 --- a/src/camera/icamera.h +++ b/src/camera/icamera.h @@ -32,6 +32,9 @@ class ICamera { public: + virtual ~ICamera() = default; + +public: virtual bool setExposureTimeUs(int value) = 0; virtual bool setGain(int value) = 0; virtual bool setLaserLevel(int value) = 0; diff --git a/src/camera/ov9281.cpp b/src/camera/ov9281.cpp index 5b6936d..a629a91 100644 --- a/src/camera/ov9281.cpp +++ b/src/camera/ov9281.cpp @@ -216,7 +216,7 @@ void OV9281::onRequestCompleted(libcamera::Request *completed_request) std::cerr << "emit empty pixels" << std::endl; } newImage.emit(img); - newPixels.emit(pixels); + // newPixels.emit(pixels); #define emit #endif } diff --git a/src/camera/veyeimx287m.cpp b/src/camera/veyeimx287m.cpp new file mode 100644 index 0000000..c821997 --- /dev/null +++ b/src/camera/veyeimx287m.cpp @@ -0,0 +1,529 @@ +#include "veyeimx287m.h" + +#include <errno.h> +#include <fcntl.h> +#include <linux/videodev2.h> +#include <stdio.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <unistd.h> + +#include <iostream> +#include <span> + +#include <QElapsedTimer> + +#include "constants.h" +#include "pixels.h" +// #include "rotaryencoder.h" + +#define LOGD(...) \ + do { \ + printf(__VA_ARGS__); \ + printf("\n"); \ + } while (0) + +#define DBG(fmt, args...) LOGD("%s:%d, " fmt, __FUNCTION__, __LINE__, ##args); + +extern uint64_t dq_elapsed_ns; +extern uint64_t get_elapsed_ns; +extern uint64_t sum_elapsed_ns; +extern uint64_t corr_elapsed_ns; +extern uint64_t max_elapsed_ns; +extern uint64_t value_elapsed_ns; +extern uint64_t rot_elapsed_ns; +extern uint64_t dropped_count; + +// constexpr char videoDevice[] = "/dev/video0"; + +VeyeIMX287m::VeyeIMX287m() {} + +VeyeIMX287m::~VeyeIMX287m() +{ + for (auto &t : m_calcThreads) { + t.request_stop(); + t.join(); + } + + m_streamThread.request_stop(); + m_streamThread.join(); + + int buffer_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + if (ioctl(m_cam_fd, VIDIOC_STREAMOFF, &buffer_type) == -1) { + std::cout << "cannot stop stream" << std::endl; + } + + for (const auto buffer : m_videoBuffers) { + if (munmap(buffer, img_size) < 0) { + DBG("Munmap failed!!."); + } + } + + if (m_cam_fd >= 0) { + if (close(m_cam_fd) == -1) { + std::cout << __func__ << ": cannot close camera: " << strerror(errno) << std::endl; + } + }; + + std::cout << "camera closed" << std::endl; +} + +std::vector<std::shared_ptr<ICamera> > VeyeIMX287m::search() +{ + // return only one camera for now + std::cout << std::boolalpha; + auto cam = std::make_shared<VeyeIMX287m>(); + + if (!cam->init()) + return {}; + + if (!cam->setExposureTimeUs(30)) + return {}; + + if (!cam->setLaserLevel(1)) + return {}; + + if (!cam->setGain(2)) + return {}; + + if (!cam->setSomething(0)) { + return {}; + } + + // m_someThread = std::jthread{[=](std::stop_token stopToken) { + // std::cout << "VeyeIMX287m: start stream" << std::endl; + // sleep(5); + + // static int i = 0; + // while (!stopToken.stop_requested()) { + // cam->setSomething(i); + // i -= 1; + // } + // }}; + + return {cam}; +} + +bool VeyeIMX287m::startStream() +{ + int buffer_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + auto ret = ioctl(m_cam_fd, VIDIOC_STREAMON, &buffer_type); + + if (ret != 0) { + DBG("ioctl(VIDIOC_STREAMON) failed %d(%s)", errno, strerror(errno)); + return false; + } + + // m_streamThread = std::jthread{&VeyeIMX287m::dequeueFrameLoop, this}; + + for (auto &t : m_calcThreads) { + t = std::jthread{&VeyeIMX287m::calcFrameLoop, this}; + } + + return true; +} + +bool VeyeIMX287m::init() +{ + if (!openCam()) + return false; + + if (!selectCam()) + return false; + + if (!initCam()) + return false; + + return true; +} + +bool VeyeIMX287m::setExposureTimeUs(int valueUs) +{ + return true; + std::cout << __func__ << ": " << valueUs << std::endl << std::flush; + + /* + * Shutter Time. Value is from 8721ns to 8721*885ns, must be integral + * multiple of 8721ns . + * 8721xN(N =1,2,3,4,5.....855) + */ + // constexpr int exposureStep{8721}; + // constexpr int maxExposureStepMultiplier{885}; + // auto valueNs = valueUs; + // valueNs = (valueNs / exposureStep) * exposureStep; + + // std::clamp(valueNs, exposureStep, exposureStep * maxExposureStepMultiplier); + // setGain(rand() % 254); + // setGain(3); + // setLaserLevel(rand() % 0x7fffffff); + // setLaserLevel(rand() % 100); + // int exp = rand() % 10; + // return setCamParam(V4L2_CID_EXPOSURE, exp * exp * exp * exp * exp * exp); + return setCamParam(V4L2_CID_EXPOSURE, valueUs); +} + +bool VeyeIMX287m::setGain(int value) +{ + std::cout << __func__ << ": " << value << std::endl << std::flush; + + // return setCamParam(V4L2_CID_GAIN, value); + // FIXME: tmp workaround for imx287llr + return true; +} + +bool VeyeIMX287m::setLaserLevel(int value) +{ + std::cout << __func__ << ": " << value << std::endl << std::flush; + + // return setCamParam(V4L2_CID_FLASH_TIMEOUT, value); + + // FIXME: tmp workaround for imx287llr + return true; +} + +bool VeyeIMX287m::setSomething(int value) +{ + std::cout << __func__ << ": " << value << std::endl << std::flush; + + // return setCamParam(V4L2_CID_FLASH_INTENSITY, value); + // FIXME: tmp workaround for imx287llr + return true; +} + +bool VeyeIMX287m::setCamParam(unsigned int v4l2controlId, int value) +{ + v4l2_control ctl{v4l2controlId, value}; + + if (ioctl(m_cam_fd, VIDIOC_S_CTRL, &ctl) < 0) { + fprintf(stderr, + "cannot set cam param: id - %d, error - '%s'\n", + v4l2controlId, + strerror(errno)); + fflush(stderr); + + return false; + } + + if (ioctl(m_cam_fd, VIDIOC_G_CTRL, &ctl) < 0) { + fprintf(stderr, + "cannot get cam param: id - %d, error - '%s'\n", + v4l2controlId, + strerror(errno)); + + fflush(stderr); + + return false; + } + + // std::cout << __func__ << ": new value is " << ctl.value << std::endl; + + return true; +} + +bool VeyeIMX287m::openCam() +{ + m_cam_fd = open(videoDevice, O_RDWR); + + if (m_cam_fd < 0) { + fprintf(stderr, "cannot open cam '%s', error: '%s'\n", videoDevice, strerror(errno)); + return false; + } + + return true; +} + +bool VeyeIMX287m::selectCam(int camIdx) +{ + int input = camIdx; + int ret = ioctl(m_cam_fd, VIDIOC_S_INPUT, &input); + + if (ret < 0) { + fprintf(stderr, "cannot select cam: idx - %d, error - '%s'\n", camIdx, strerror(errno)); + + return false; + } + + return true; +} + +bool VeyeIMX287m::initCam() +{ + v4l2_format format; + memset(&format, 0, sizeof(v4l2_format)); + format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + format.fmt.pix.pixelformat = V4L2_PIX_FMT_GREY; + format.fmt.pix.width = img_width; + format.fmt.pix.height = img_height; + + int ret = ioctl(m_cam_fd, VIDIOC_TRY_FMT, &format); + + if (ret < 0) { + fprintf(stderr, "cannot try cam format: error - '%s'\n", strerror(errno)); + + return false; + } + + // TODO: remove this? + format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + + ret = ioctl(m_cam_fd, VIDIOC_S_FMT, &format); + + if (ret < 0) { + fprintf(stderr, "cannot set cam format: error - '%s'\n", strerror(errno)); + + return false; + } + + struct v4l2_requestbuffers request; + request.count = BUFFER_COUNT; + request.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + request.memory = V4L2_MEMORY_MMAP; + ret = ioctl(m_cam_fd, VIDIOC_REQBUFS, &request); + + if (ret < 0) { + fprintf(stderr, "cannot set cam request buffers: ioctl error - '%s'\n", strerror(errno)); + + return false; + } + + if (request.count < BUFFER_COUNT) { + fprintf(stderr, "cannot set cam request buffers\n"); + + return false; + } + + struct v4l2_buffer buffer; + memset(&buffer, 0, sizeof(buffer)); + buffer.type = request.type; + buffer.memory = V4L2_MEMORY_MMAP; + + for (uint32_t i = 0; i < request.count; i++) { + buffer.index = i; + ret = ioctl(m_cam_fd, VIDIOC_QUERYBUF, &buffer); + + if (ret < 0) { + DBG("ioctl(VIDIOC_QUERYBUF) failed %d(%s)", errno, strerror(errno)); + return false; + } + + DBG("buffer.length: %d", buffer.length); + DBG("buffer.m.offset: %d", buffer.m.offset); + m_videoBuffers[i] = (uint8_t *) + mmap(NULL, buffer.length, PROT_READ | PROT_WRITE, MAP_SHARED, m_cam_fd, buffer.m.offset); + if (m_videoBuffers[i] == MAP_FAILED) { + DBG("mmap() failed %d(%s)", errno, strerror(errno)); + return false; + } + + buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buffer.memory = V4L2_MEMORY_MMAP; + buffer.index = i; + ret = ioctl(m_cam_fd, VIDIOC_QBUF, &buffer); + if (ret != 0) { + DBG("ioctl(VIDIOC_QBUF) failed %d(%s)", errno, strerror(errno)); + return false; + } + } + + // int buffer_type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + // ret = ioctl(m_cam_fd, VIDIOC_STREAMON, &buffer_type); + // if (ret != 0) + // { + // DBG("ioctl(VIDIOC_STREAMON) failed %d(%s)", errno, strerror(errno)); + // return false; + // } + + DBG("cam init done."); + + return true; +} + +void VeyeIMX287m::dequeueFrameLoop(std::stop_token stopToken) +{ + // std::cout << "VeyeIMX287m: start stream" << std::endl; + + // while (!stopToken.stop_requested()) { + // size_t imageIndex{}; + + // if (!dequeueImageBuffer(imageIndex)) + // // break; + // continue; + // } + + // std::cout << "VeyeIMX287m: stream interruption requested" << std::endl; +} + +void VeyeIMX287m::calcFrameLoop(std::stop_token stopToken) +{ + while (!stopToken.stop_requested()) { + size_t bufferIdx{}; + + if (!dequeueImageBuffer(bufferIdx)) { + std::cout << "AAAAAAAAAAAAAAAAAA" << std::endl; + continue; + } + + // std::lock_guard img_lock{m_imageMutexes[bufferIdx]}; + auto &image = m_images[bufferIdx]; + + { + QElapsedTimer t; + t.start(); + // std::lock_guard buffer_lock{m_bufferMutexes[bufferIdx]}; + memcpy(&image.data, m_videoBuffers[bufferIdx], img_size); + get_elapsed_ns += t.nsecsElapsed(); + } + + image.rotate(); + image.pixels(); + + setCamParam(V4L2_CID_EXPOSURE, 18); + } +} + +// Image &VeyeIMX287m::dequeueImageBuffer() +// bool VeyeIMX287m::dequeueImageBuffer(Image &image) +bool VeyeIMX287m::dequeueImageBuffer(size_t &imageIndex) +// TODO: get Image from video_buffer_ptr +{ + static struct timeval curr, prev; + static uint16_t counter = 0; + gettimeofday(&curr, NULL); + + double elapsedTime = (curr.tv_sec - prev.tv_sec) * 1000.0; // sec to ms + elapsedTime += (curr.tv_usec - prev.tv_usec) / 1000.0; // us to ms + + if (elapsedTime > 1000.) { + fprintf(stderr, + "fps: %d\tdropped: %d\tsec: %d\tdq: %d\tget: %d\trot: %d\tsum: %d,\tcorr: " + "%d,\tval: %d\n", + counter, + dropped_count, + curr.tv_sec % 1000, + dq_elapsed_ns / 1000 / counter, + get_elapsed_ns / 1000 / counter, + rot_elapsed_ns / 1000 / counter, + sum_elapsed_ns / 1000 / counter, + corr_elapsed_ns / 1000 / counter, + // max_elapsed_ns / 1000 / counter, + value_elapsed_ns / 1000 / counter); + + dq_elapsed_ns = 0; + get_elapsed_ns = 0; + sum_elapsed_ns = 0; + corr_elapsed_ns = 0; + max_elapsed_ns = 0; + value_elapsed_ns = 0; + rot_elapsed_ns = 0; + dropped_count = 0; + + counter = 0; + prev = curr; + } + + int ret; + struct v4l2_buffer buffer; + + memset(&buffer, 0, sizeof(buffer)); + buffer.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; + buffer.memory = V4L2_MEMORY_MMAP; + static uint16_t requestIdx{0}; + // buffer.index = BUFFER_COUNT; + buffer.index = requestIdx++ % BUFFER_COUNT; + + { + QElapsedTimer t; + t.start(); + // { + // std::lock_guard<std::mutex> lock(m_queueMtx); + + // if (m_buffersQueue.size() >= BUFFER_COUNT) { + // // std::cout << "frame skip" << std::endl; + // dq_elapsed_ns += t.nsecsElapsed(); + // return false; + // } + // } + + auto oldIdx = buffer.index; + // m_bufferMutexes[buffer.index].lock(); + std::lock_guard<std::mutex> lock(m_camMtx); + ret = ioctl(m_cam_fd, VIDIOC_DQBUF, &buffer); + // m_bufferMutexes[buffer.index].unlock(); + auto newIdx = buffer.index; + + if (oldIdx != newIdx) { + // std::cout << "AAAAAAAAAAAAAA " << oldIdx << ' ' << newIdx << std::endl; + } + + if (ret != 0) { + DBG("ioctl(VIDIOC_DQBUF) failed %d(%s)", errno, strerror(errno)); + return false; + } + + if (buffer.index < 0 || buffer.index >= BUFFER_COUNT) { + DBG("invalid buffer index: %d", buffer.index); + return false; + } + + // std::lock_guard<std::mutex> lock(m_queueMtx); + // m_buffersQueue.push(buffer.index); + ++counter; + dq_elapsed_ns += t.nsecsElapsed(); + } + + // auto &image = video_buffer_ptr[buffer.index]; + imageIndex = buffer.index; + auto &image = m_images[buffer.index]; + image.height = img_height; + image.width = img_width; + // TODO: fill + // image.counters.encoderPosition = RotaryEncoder::instance()->position(); + image.counters.measurementCounter = buffer.sequence; + + static int64_t prevCounter = buffer.sequence; + dropped_count += buffer.sequence - prevCounter - 1; + prevCounter = buffer.sequence; + + image.counters.timestampUs = buffer.timestamp.tv_sec * 1000 * 1000 + buffer.timestamp.tv_usec; + + // { + // QElapsedTimer t; + // t.start(); + // memcpy(&image.data, m_videoBuffers[buffer.index], img_size); + // // std::cout << (void *) video_buffer_ptr[buffer.index] << std::endl; + // get_elapsed_ns += t.nsecsElapsed(); + // } + + { + std::lock_guard<std::mutex> lock(m_camMtx); + ret = ioctl(m_cam_fd, VIDIOC_QBUF, &buffer); + } + + if (ret != 0) { + DBG("ioctl(VIDIOC_QBUF) failed %d(%s)", errno, strerror(errno)); + return false; + } + + return true; +} + +bool VeyeIMX287m::getImage(Image &image) +{ + size_t bufferIdx{}; + + if (!dequeueImageBuffer(bufferIdx)) { + std::cout << "AAAAAAAAAAAAAAAAAA" << std::endl; + return false; + } + + image = std::move(m_images[bufferIdx]); + { + QElapsedTimer t; + t.start(); + memcpy(&image.data, m_videoBuffers[bufferIdx], img_size); + get_elapsed_ns += t.nsecsElapsed(); + } + + return true; +} diff --git a/src/camera/veyeimx287m.h b/src/camera/veyeimx287m.h new file mode 100644 index 0000000..9986e59 --- /dev/null +++ b/src/camera/veyeimx287m.h @@ -0,0 +1,73 @@ +#pragma once + +#include <cstdint> + +#include <queue> +#include <thread> + +#include "constants.h" +#include "image.h" + +#include "icamera.h" + +class VeyeIMX287m : public ICamera +{ + constexpr static char videoDevice[] = "/dev/video0"; + +public: + using buffer_t = std::array<uint8_t, img_size>; + +public: + VeyeIMX287m(); + ~VeyeIMX287m() override; + +public: + static std::vector<std::shared_ptr<ICamera>> search(); + +public: + bool startStream() override; + + bool init(); + + bool setExposureTimeUs(int value) override; + bool setGain(int value) override; + + bool setLaserLevel(int value) override; + + bool setSomething(int value) override; + + // bool dequeueImageBuffer(Image &image); + bool dequeueImageBuffer(size_t &image); + bool getImage(Image &image); + // Image &getImage(); + +public: + libcamera::Signal<std::shared_ptr<Pixels>> newPixels; + libcamera::Signal<std::shared_ptr<Image>> newImage; + +private: + bool setCamParam(unsigned int v4l2controlId, int value); + bool openCam(); + bool selectCam(int camIdx = 0); + bool initCam(); + + void dequeueFrameLoop(std::stop_token stopToken); + void calcFrameLoop(std::stop_token stopToken); + +private: + int m_cam_fd{-1}; + + static constexpr uint8_t BUFFER_COUNT{8}; + + std::array<std::mutex, BUFFER_COUNT> m_imageMutexes; + std::array<Image, BUFFER_COUNT> m_images; + std::array<std::mutex, BUFFER_COUNT> m_bufferMutexes; + std::array<uint8_t *, BUFFER_COUNT> m_videoBuffers; + + // std::mutex m_queueMtx; + std::mutex m_camMtx; + std::queue<size_t> m_buffersQueue; + + std::jthread m_streamThread; + std::jthread m_calcThreads[4]; +}; diff --git a/src/image.cpp b/src/image.cpp index c2ee5b4..e22c9bb 100644 --- a/src/image.cpp +++ b/src/image.cpp @@ -111,36 +111,21 @@ void Image::rotate() { QElapsedTimer t; t.start(); - // start_timer(rotate); - using namespace std; - - // Image::data_t &d = *data; -#pragma omp parallel -#pragma omp for - for (size_t i = 0; i < img_height; ++i) { - for (size_t j = 0; j < img_width; ++j) { - // for (size_t j = 0; j < img_width; j += 4) { + for (size_t j = 0; j < img_width; ++j) { + for (size_t i = 0; i < img_height; ++i) { rotated_cw[j][i] = data[img_height - i - 1][j]; - // rotated_cw[j][i] = d[img_height - i - 1][j]; - - // rotated_cw[j + 0][i] = data[img_height - i - 1][j + 0]; - // rotated_cw[j + 1][i] = data[img_height - i - 1][j + 1]; - // rotated_cw[j + 2][i] = data[img_height - i - 1][j + 2]; - // rotated_cw[j + 3][i] = data[img_height - i - 1][j + 3]; - - // rotated_cw[j][i] = dataAt(img_height - i - 1, j); } } - // stop_timer(rotate); rot_elapsed_ns += t.nsecsElapsed(); } -std::shared_ptr<Pixels> Image::pixels() const +Pixels Image::pixels() const { - auto result = std::make_shared<Pixels>(); - result->counters = counters; + // auto result = std::make_shared<Pixels>(); + Pixels result; + result.counters = counters; start_timer(process_columns); // std::transform(std::execution::par_unseq, @@ -149,19 +134,12 @@ std::shared_ptr<Pixels> Image::pixels() const // result->pixels.begin(), // [](const auto &column) -> float { return process_column(column); }); -#pragma omp chunk -#pragma omp parallel for - for (size_t i = 0; i < img_width; i++) { - result->pixels[i] = process_column(rotated_cw[i]); + // #pragma omp chunk + // #pragma omp parallel for + for (size_t i = 0; i < img_width / 4; i++) { + result.pixels[i] = process_column(rotated_cw[i]); } - // for (size_t i = 640 - 5; i < 640 + 5; ++i) { - // std::cout << result->pixels[i] << ' '; - // } - // std::cout << std::endl; - - stop_timer(process_columns); - return result; } diff --git a/src/image.h b/src/image.h index b4e8a58..15b5daa 100644 --- a/src/image.h +++ b/src/image.h @@ -10,6 +10,11 @@ class Pixels; // TODO: template struct Image { + // Image(Image &other) { std::cerr << __func__ << ": don't copy me please" << std::endl; } + Image() = default; + Image(Image &other) = delete; + Image(Image &&other) = delete; + Image &operator=(Image &&other) = default; int width{0}; int height{0}; // uint8_t data[img_height][img_width] = {{0}}; @@ -30,8 +35,12 @@ struct Image // unsigned int stride{0}; libcamera::PixelFormat pixelFormat{0}; Counters counters{}; + bool hasInputData{false}; void rotate(); - std::shared_ptr<Pixels> pixels() const; + Pixels pixels() const; void copyFromData(const void* src, size_t size); + +private: + Image &operator=(Image &other) = delete; }; diff --git a/src/main.cpp b/src/main.cpp index fd5bd79..e05262a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,5 @@ #include <chrono> +#include <csignal> #include <errno.h> #include <fstream> #include <iostream> @@ -11,6 +12,7 @@ #include "calibration.h" #include "camera/innomakerov9281.h" #include "camera/ov9281.h" +#include "camera/veyeimx287m.h" #include "dumps.h" #include "fuck_intel.h" #include "genetic_algos.h" @@ -134,7 +136,17 @@ bool initLaser(); int main(int argc, char* argv[]) { + auto sigHandler = [](int s) { + std::cout << "got signal " << s << std::endl; + std::signal(s, SIG_DFL); + qApp->quit(); + }; + + std::signal(SIGINT, sigHandler); + std::signal(SIGTERM, sigHandler); + QCoreApplication app(argc, argv); + // QTimer::singleShot(4000, qApp, &QCoreApplication::quit); QList<QFuture<void>> initializers; @@ -366,7 +378,8 @@ int main(int argc, char* argv[]) #endif // const auto cameras = cm->cameras(); // const auto cameras = OV9281::search(cm); - const auto cameras = InnoMakerOV9281::search(); + // const auto cameras = InnoMakerOV9281::search(); + const auto cameras = VeyeIMX287m::search(); // const auto cameras = if (cameras.empty()) @@ -405,31 +418,60 @@ int main(int argc, char* argv[]) } QHttpServer qHttpServer; - qHttpServer.route("/v1/sensor/image", [&]() { + auto httpGetImage = [&]() -> QHttpServerResponse { + // return QHttpServerResponse::StatusCode::ServiceUnavailable; // std::cout << "http: image" << std::endl << std::flush; // FILE *f = fopen("/tmp/img.pgm", "w"); // static bool save = false; + auto cam = dynamic_cast<VeyeIMX287m *>(camera.get()); + + if (!cam) { + qDebug() << "NO CAM"; + return QHttpServerResponse::StatusCode::ServiceUnavailable; + } + + Image img; + // yeaah + ::img = &img; + if (!cam->getImage(img)) { + qDebug() << "cannot get image"; + return QHttpServerResponse::StatusCode::ServiceUnavailable; + } pgm_save(::img); // save = false; std::lock_guard<std::mutex> lg(pgm_image_mtx); // qDebug() << "mutex locked"; // qDebug() << "image saved to array"; - return QByteArray((const char*) pgm_image, pgm_image_size); - }); - qHttpServer.route("/v1/sensor/image2", [&]() { - // std::cout << "http: image2" << std::endl; - pgm_save(::img); - - std::lock_guard<std::mutex> lg(pgm_image_mtx); - // qDebug() << "image2"; - return QByteArray((const char*) pgm_image, pgm_image_size); - }); + return QHttpServerResponse{QByteArray((const char *) pgm_image, pgm_image_size), + QHttpServerResponse::StatusCode::Ok}; + }; + qHttpServer.route("/v1/sensor/image", httpGetImage); + qHttpServer.route("/v1/sensor/image2", httpGetImage); // qHttpServer.route("/v1/sensor/exposureTimeUs", [&]() { // // std::lock_guard<std::mutex> lg(pgm_image_mtx); // return "123"; // }); - qHttpServer.route("/v1/pixels", [&]() { + qHttpServer.route("/v1/pixels", [&]() -> QHttpServerResponse { // std::cout << "http: pixels" << std::endl; + // return QHttpServerResponse::StatusCode::ServiceUnavailable; + + auto cam = dynamic_cast<VeyeIMX287m *>(camera.get()); + + if (!cam) { + qDebug() << "NO CAM"; + return QHttpServerResponse::StatusCode::ServiceUnavailable; + } + + Image img; + // yeaah + ::img = &img; + if (!cam->getImage(img)) { + qDebug() << "cannot get image"; + return QHttpServerResponse::StatusCode::ServiceUnavailable; + } + + ::pixels = img.pixels(); + std::lock_guard<std::mutex> lg(pgm_image_mtx); QJsonArray pixels; @@ -444,8 +486,8 @@ int main(int argc, char* argv[]) json["pixels"] = pixels; // json["encoderPosition"] = qint64{encoder.position()}; // FIXME: get prom pixels struct - json["measurementCounter"] = qint64{img->counters.measurementCounter}; - json["timestampUs"] = qint64(img->counters.timestampUs); + json["measurementCounter"] = qint64{img.counters.measurementCounter}; + json["timestampUs"] = qint64(img.counters.timestampUs); const auto lines = pixelsToLines(::pixels); @@ -466,6 +508,7 @@ int main(int argc, char* argv[]) qHttpServer.route("/v1/profile", [&]() -> QHttpServerResponse { // std::cout << "http: profile" << std::endl; + return QHttpServerResponse::StatusCode::ServiceUnavailable; std::lock_guard<std::mutex> lg(pgm_image_mtx); if (!::calibrationTableZ || !::calibrationTableX) @@ -672,16 +715,16 @@ int main(int argc, char* argv[]) qDebug() << "listen: " << qHttpServer.listen(QHostAddress::Any, 8081); - QFuture<void> future = QtConcurrent::run([]() { - Port port(8080); - Address addr(Ipv4::any(), port); + // QFuture<void> future = QtConcurrent::run([]() { + // Port port(8080); + // Address addr(Ipv4::any(), port); - HttpService httpService(addr); + // HttpService httpService(addr); - size_t threads_count = 1; - httpService.init(threads_count); - httpService.start(); - }); + // size_t threads_count = 1; + // httpService.init(threads_count); + // httpService.start(); + // }); //////////////////////////////////////////////////////////////////////////// std::clog << std::flush; @@ -694,8 +737,8 @@ int main(int argc, char* argv[]) auto result = app.exec(); - future.cancel(); - future.waitForFinished(); + // future.cancel(); + // future.waitForFinished(); // for (auto& [fd, mem] : mappedBuffers_) // { |
