diff options
| author | Nikita Kostovsky <nikita@kostovsky.me> | 2025-11-29 23:29:36 +0100 |
|---|---|---|
| committer | Nikita Kostovsky <nikita@kostovsky.me> | 2025-11-29 23:29:36 +0100 |
| commit | 5edbc081d61d47e5938a76fcb201aed4b148f1b4 (patch) | |
| tree | 8c7dc3beb0769d1ecf11262ec9bf20255e2d2ac3 | |
| parent | fe1a89dbd83e10bfb480962a511fa0f43885eb77 (diff) | |
try to use QFuture to keep frames order
| -rw-r--r-- | src/camera/veyeimx287m.cpp | 94 |
1 files changed, 49 insertions, 45 deletions
diff --git a/src/camera/veyeimx287m.cpp b/src/camera/veyeimx287m.cpp index 6df5a3e..c87480b 100644 --- a/src/camera/veyeimx287m.cpp +++ b/src/camera/veyeimx287m.cpp @@ -12,6 +12,7 @@ #include <iostream> #include <QElapsedTimer> +#include <QtConcurrent/QtConcurrentRun> // orpheus #include "camera/veye_i2c.h" @@ -229,9 +230,7 @@ VeyeIMX287m::~VeyeIMX287m() if (m_cam_fd >= 0) { if (close(m_cam_fd) == -1) { - std::cout << __func__ - << ": cannot close camera: " << strerror(errno) - << std::endl; + std::cout << __func__ << ": cannot close camera: " << strerror(errno) << std::endl; } }; @@ -270,8 +269,8 @@ bool VeyeIMX287m::startStream() const auto ret = ioctl(m_cam_fd, VIDIOC_STREAMON, &radxa_buf_type); if (ret != 0) { - std::cerr << "ioctl(VIDIOC_STREAMON) failed: " << errno << " (" - << strerror(errno) << ")" << std::endl; + std::cerr << "ioctl(VIDIOC_STREAMON) failed: " << errno << " (" << strerror(errno) << ")" + << std::endl; return false; } @@ -314,8 +313,8 @@ bool VeyeIMX287m::set_autoExposure(const bool enable) { using namespace veye::imx287m; - const uint32_t value = static_cast<uint32_t>( - enable ? ExposureMode::AutoExposureContinious : ExposureMode::Manual); + const uint32_t value = static_cast<uint32_t>(enable ? ExposureMode::AutoExposureContinious + : ExposureMode::Manual); return m_i2c->write(static_cast<uint16_t>(Register::Exposure_Mode), value); } @@ -324,23 +323,21 @@ std::optional<bool> VeyeIMX287m::get_autoExposure() { using namespace veye::imx287m; - const auto value = m_i2c->read( - static_cast<uint32_t>(Register::Exposure_Mode)); + const auto value = m_i2c->read(static_cast<uint32_t>(Register::Exposure_Mode)); if (!value) { return {}; } - return *value - == static_cast<uint32_t>(ExposureMode::AutoExposureContinious); + return *value == static_cast<uint32_t>(ExposureMode::AutoExposureContinious); } bool VeyeIMX287m::set_autoGain(const bool enable) { using namespace veye::imx287m; - const uint32_t value = static_cast<uint32_t>( - enable ? GainMode::AutoGainContinious : GainMode::Manual); + const uint32_t value = static_cast<uint32_t>(enable ? GainMode::AutoGainContinious + : GainMode::Manual); return m_i2c->write(static_cast<uint16_t>(Register::Gain_Mode), value); } @@ -402,10 +399,7 @@ 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)); + fprintf(stderr, "cannot open cam '%s', error: '%s'\n", videoDevice, strerror(errno)); return false; } @@ -430,9 +424,7 @@ bool VeyeIMX287m::initCam() ret = ioctl(m_cam_fd, VIDIOC_TRY_FMT, &format); if (ret < 0) { - fprintf(stderr, - "cannot try cam format: error - '%s'\n", - strerror(errno)); + fprintf(stderr, "cannot try cam format: error - '%s'\n", strerror(errno)); return false; } @@ -443,9 +435,7 @@ bool VeyeIMX287m::initCam() ret = ioctl(m_cam_fd, VIDIOC_S_FMT, &format); if (ret < 0) { - fprintf(stderr, - "cannot set cam format: error - '%s'\n", - strerror(errno)); + fprintf(stderr, "cannot set cam format: error - '%s'\n", strerror(errno)); return false; } @@ -501,9 +491,7 @@ bool VeyeIMX287m::initCam() ret = ioctl(m_cam_fd, VIDIOC_REQBUFS, &rb); if (ret < 0) { - fprintf(stderr, - "cannot set cam request buffers: ioctl error - '%s'\n", - strerror(errno)); + fprintf(stderr, "cannot set cam request buffers: ioctl error - '%s'\n", strerror(errno)); return false; } @@ -519,8 +507,7 @@ bool VeyeIMX287m::initCam() std::cout << "query buffers" << std::endl; for (uint32_t i = 0; i < rb.count; i++) { - std::cout << "-----------------------------------------------------" - << std::endl; + std::cout << "-----------------------------------------------------" << std::endl; struct v4l2_buffer buf; struct v4l2_plane planes[VIDEO_MAX_PLANES]; @@ -536,8 +523,8 @@ bool VeyeIMX287m::initCam() ret = ioctl(m_cam_fd, VIDIOC_QUERYBUF, &buf); if (ret < 0) { - std::cerr << "ioctl(VIDIOC_QUERYBUF) failed: " << errno << " (" - << strerror(errno) << ")" << std::endl; + std::cerr << "ioctl(VIDIOC_QUERYBUF) failed: " << errno << " (" << strerror(errno) + << ")" << std::endl; return false; } @@ -551,8 +538,7 @@ bool VeyeIMX287m::initCam() m_buffers[i].mem = mmap(0, length, PROT_READ | PROT_WRITE, MAP_SHARED, m_cam_fd, offset); if (m_buffers[i].mem == MAP_FAILED) { - std::cerr << "mmap() failed: " << errno << " (" << strerror(errno) - << ")" << std::endl; + std::cerr << "mmap() failed: " << errno << " (" << strerror(errno) << ")" << std::endl; std::cerr << "length: " << length << std::endl; std::cerr << "offset: " << offset << std::endl; @@ -564,8 +550,8 @@ bool VeyeIMX287m::initCam() ret = ioctl(m_cam_fd, VIDIOC_QBUF, &buf); if (ret != 0) { - std::cerr << "ioctl(VIDIOC_QBUF) failed: " << errno << " (" - << strerror(errno) << ")" << std::endl; + std::cerr << "ioctl(VIDIOC_QBUF) failed: " << errno << " (" << strerror(errno) << ")" + << std::endl; return false; } } @@ -587,6 +573,9 @@ void VeyeIMX287m::getFrameLoop(std::stop_token stopToken) { QElapsedTimer t; + uint8_t threadIdx{0}; + std::array<QFuture<uint8_t>, BUFFER_COUNT> futures; + while (!stopToken.stop_requested()) { size_t bufferIdx{std::numeric_limits<size_t>::max()}; @@ -594,24 +583,39 @@ void VeyeIMX287m::getFrameLoop(std::stop_token stopToken) continue; } - const auto &image = m_buffers[bufferIdx].image; + const uint8_t i = threadIdx % BUFFER_COUNT; + + futures[i].waitForFinished(); + + const auto &image = m_buffers[i].image; { t.start(); - auto &src = *(Image::radxa_data_t *) m_buffers[bufferIdx].mem; + auto &src = *(Image::radxa_data_t *) m_buffers[i].mem; auto &dst = image->data; Image::copy(dst, src); get_elapsed_ns += t.nsecsElapsed(); } + futures[i] = QtConcurrent::run([this, i]() { + const auto image = m_buffers[i].image; + image->rotate(); + return i; + }).then([this](const uint8_t i) { + const auto image = m_buffers[i].image; + const auto pixels = image->sharedPixels(); + return i; + }); + ++processedCounter; - m_sync.freeRawBuffers.acquire(); - // TODO: check that queue cannot contain duplicate indices due to ioctl - // TODO: separate copied images from raw buffers - m_sync.rawBufferIndices.enqueue(bufferIdx); - m_sync.usedRawBuffers.release(); + ++threadIdx; + // m_sync.freeRawBuffers.acquire(); + // // TODO: check that queue cannot contain duplicate indices due to ioctl + // // TODO: separate copied images from raw buffers + // m_sync.rawBufferIndices.enqueue(bufferIdx); + // m_sync.usedRawBuffers.release(); // image->rotate(); // const auto pixels = image->sharedPixels(); @@ -715,8 +719,8 @@ bool VeyeIMX287m::dequeueImageBuffer(size_t &imageIndex) } if (ret != 0) { - std::cerr << "ioctl(VIDIOC_DQBUF) failed: " << errno << " (" - << strerror(errno) << ")" << std::endl; + std::cerr << "ioctl(VIDIOC_DQBUF) failed: " << errno << " (" << strerror(errno) << ")" + << std::endl; return false; } @@ -746,8 +750,8 @@ bool VeyeIMX287m::dequeueImageBuffer(size_t &imageIndex) } if (ret != 0) { - std::cerr << "ioctl(VIDIOC_QBUF) failed: " << errno << " (" - << strerror(errno) << ")" << std::endl; + std::cerr << "ioctl(VIDIOC_QBUF) failed: " << errno << " (" << strerror(errno) << ")" + << std::endl; return false; } |
