summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikita Kostovsky <nikita@kostovsky.me>2025-11-29 23:29:36 +0100
committerNikita Kostovsky <nikita@kostovsky.me>2025-11-29 23:29:36 +0100
commit5edbc081d61d47e5938a76fcb201aed4b148f1b4 (patch)
tree8c7dc3beb0769d1ecf11262ec9bf20255e2d2ac3
parentfe1a89dbd83e10bfb480962a511fa0f43885eb77 (diff)
try to use QFuture to keep frames order
-rw-r--r--src/camera/veyeimx287m.cpp94
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;
}