summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorNikita Kostovsky <luntik2012@gmail.com>2025-01-26 11:55:53 +0100
committerNikita Kostovsky <luntik2012@gmail.com>2025-01-26 11:55:53 +0100
commit90503471c49ef6ab795a61a2dc7df1e35761fa7e (patch)
treec919bc493838185eae947a80e16b6f593d825fbc /src
parent626f08162b07a49e8683bfb04a71ac02faa9b12d (diff)
use callbacks for pixels/image, update http resps, load calibration tables in separate threads
Diffstat (limited to 'src')
-rw-r--r--src/camera/icamera.h6
-rw-r--r--src/camera/innomakerov9281.cpp152
-rw-r--r--src/camera/innomakerov9281.h6
-rw-r--r--src/camera/ov9281.h13
4 files changed, 135 insertions, 42 deletions
diff --git a/src/camera/icamera.h b/src/camera/icamera.h
index 4245a68..588b23e 100644
--- a/src/camera/icamera.h
+++ b/src/camera/icamera.h
@@ -32,8 +32,14 @@
class ICamera
{
public:
+ virtual bool setExposureTimeUs(int value) = 0;
+ virtual bool setGain(int value) = 0;
+
+public:
libcamera::Signal<std::shared_ptr<Pixels>> newPixels;
libcamera::Signal<std::shared_ptr<Image>> newImage;
+ std::function<void(std::shared_ptr<Pixels>)> newPixelsCallback;
+ std::function<void(std::shared_ptr<Image>)> newImageCallback;
public:
virtual bool startStream() = 0;
diff --git a/src/camera/innomakerov9281.cpp b/src/camera/innomakerov9281.cpp
index a2d3136..73ceacb 100644
--- a/src/camera/innomakerov9281.cpp
+++ b/src/camera/innomakerov9281.cpp
@@ -15,7 +15,8 @@
// #include "rotaryencoder.h"
#define LOGD(...) \
- do { \
+ do \
+ { \
printf(__VA_ARGS__); \
printf("\n"); \
} while (0)
@@ -38,19 +39,23 @@ InnoMakerOV9281::~InnoMakerOV9281()
int ret{-1};
- for (int i = 0; i < BUFFER_COUNT; ++i) {
+ for (int i = 0; i < BUFFER_COUNT; ++i)
+ {
ret = munmap(video_buffer_ptr[i], img_size);
- if (ret < 0) {
+ if (ret < 0)
+ {
DBG("Munmap failed!!.");
}
}
// std::cout << __func__ << std::endl;
- if (m_cam_fd >= 0) {
+ if (m_cam_fd >= 0)
+ {
int ret = close(m_cam_fd);
- if (ret == -1) {
+ if (ret == -1)
+ {
// std::cout << __func__
// << ": cannot close camera: " << strerror(errno)
// << std::endl;
@@ -69,7 +74,7 @@ std::vector<std::shared_ptr<ICamera> > InnoMakerOV9281::search()
if (!cam->init())
return {};
- if (!cam->setExposureTimeMs(3000))
+ if (!cam->setExposureTimeUs(3000))
return {};
if (!cam->setGain(3000))
@@ -83,20 +88,30 @@ bool InnoMakerOV9281::startStream()
m_streamThread = std::jthread{[&](std::stop_token stopToken) {
std::cout << "InnoMakerOV9281: start stream" << std::endl;
- while (!stopToken.stop_requested()) {
+ while (!stopToken.stop_requested())
+ {
std::shared_ptr<Image> image = std::make_shared<Image>();
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);
+ // std::cout << "emit new image" << std::endl << std::flush;
+ // newImage.emit(image);
+ if (newImageCallback)
+ {
+ newImageCallback(image);
+ }
+ // newPixels.emit(pixels);
+ if (newPixelsCallback)
+ {
+ auto pixels = image->pixels();
+ newPixelsCallback(pixels);
+ }
}
#define emit
#endif
- std::cout << "InnoMakerOV9281: stream interruption requested" << std::endl;
+ std::cout << "InnoMakerOV9281: stream interruption requested"
+ << std::endl;
}};
return true;
@@ -116,9 +131,23 @@ bool InnoMakerOV9281::init()
return true;
}
-bool InnoMakerOV9281::setExposureTimeMs(int value)
+bool InnoMakerOV9281::setExposureTimeUs(int valueUs)
{
- return setCamParam(V4L2_CID_EXPOSURE, value);
+ 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);
+
+ return setCamParam(V4L2_CID_EXPOSURE, valueUs);
}
bool InnoMakerOV9281::setGain(int value)
@@ -132,7 +161,8 @@ bool InnoMakerOV9281::setCamParam(unsigned int v4l2controlId, int value)
int ret = ioctl(m_cam_fd, VIDIOC_S_CTRL, &ctl);
- if (ret < 0) {
+ if (ret < 0)
+ {
fprintf(stderr,
"cannot set cam param: id - %d, error - '%s'\n",
v4l2controlId,
@@ -141,6 +171,20 @@ bool InnoMakerOV9281::setCamParam(unsigned int v4l2controlId, int value)
return false;
}
+ ret = ioctl(m_cam_fd, VIDIOC_G_CTRL, &ctl);
+
+ if (ret < 0)
+ {
+ fprintf(stderr,
+ "cannot get cam param: id - %d, error - '%s'\n",
+ v4l2controlId,
+ strerror(errno));
+
+ return false;
+ }
+
+ std::cout << __func__ << ": new value is " << ctl.value << std::endl;
+
return true;
}
@@ -148,8 +192,12 @@ bool InnoMakerOV9281::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));
+ if (m_cam_fd < 0)
+ {
+ fprintf(stderr,
+ "cannot open cam '%s', error: '%s'\n",
+ videoDevice,
+ strerror(errno));
return false;
}
@@ -161,8 +209,12 @@ bool InnoMakerOV9281::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));
+ if (ret < 0)
+ {
+ fprintf(stderr,
+ "cannot select cam: idx - %d, error - '%s'\n",
+ camIdx,
+ strerror(errno));
return false;
}
@@ -181,8 +233,11 @@ bool InnoMakerOV9281::initCam()
int ret = ioctl(m_cam_fd, VIDIOC_TRY_FMT, &format);
- if (ret < 0) {
- fprintf(stderr, "cannot try cam format: error - '%s'\n", strerror(errno));
+ if (ret < 0)
+ {
+ fprintf(stderr,
+ "cannot try cam format: error - '%s'\n",
+ strerror(errno));
return false;
}
@@ -192,8 +247,11 @@ bool InnoMakerOV9281::initCam()
ret = ioctl(m_cam_fd, VIDIOC_S_FMT, &format);
- if (ret < 0) {
- fprintf(stderr, "cannot set cam format: error - '%s'\n", strerror(errno));
+ if (ret < 0)
+ {
+ fprintf(stderr,
+ "cannot set cam format: error - '%s'\n",
+ strerror(errno));
return false;
}
@@ -204,13 +262,17 @@ bool InnoMakerOV9281::initCam()
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));
+ if (ret < 0)
+ {
+ fprintf(stderr,
+ "cannot set cam request buffers: ioctl error - '%s'\n",
+ strerror(errno));
return false;
}
- if (request.count < BUFFER_COUNT) {
+ if (request.count < BUFFER_COUNT)
+ {
fprintf(stderr, "cannot set cam request buffers\n");
return false;
@@ -221,20 +283,27 @@ bool InnoMakerOV9281::initCam()
buffer.type = request.type;
buffer.memory = V4L2_MEMORY_MMAP;
- for (uint32_t i = 0; i < request.count; i++) {
+ for (uint32_t i = 0; i < request.count; i++)
+ {
buffer.index = i;
ret = ioctl(m_cam_fd, VIDIOC_QUERYBUF, &buffer);
- if (ret < 0) {
+ 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);
- video_buffer_ptr[i] = (uint8_t *)
- mmap(NULL, buffer.length, PROT_READ | PROT_WRITE, MAP_SHARED, m_cam_fd, buffer.m.offset);
- if (video_buffer_ptr[i] == MAP_FAILED) {
+ video_buffer_ptr[i] = (uint8_t *) mmap(NULL,
+ buffer.length,
+ PROT_READ | PROT_WRITE,
+ MAP_SHARED,
+ m_cam_fd,
+ buffer.m.offset);
+ if (video_buffer_ptr[i] == MAP_FAILED)
+ {
DBG("mmap() failed %d(%s)", errno, strerror(errno));
return false;
}
@@ -243,7 +312,8 @@ bool InnoMakerOV9281::initCam()
buffer.memory = V4L2_MEMORY_MMAP;
buffer.index = i;
ret = ioctl(m_cam_fd, VIDIOC_QBUF, &buffer);
- if (ret != 0) {
+ if (ret != 0)
+ {
DBG("ioctl(VIDIOC_QBUF) failed %d(%s)", errno, strerror(errno));
return false;
}
@@ -251,7 +321,8 @@ bool InnoMakerOV9281::initCam()
int buffer_type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
ret = ioctl(m_cam_fd, VIDIOC_STREAMON, &buffer_type);
- if (ret != 0) {
+ if (ret != 0)
+ {
DBG("ioctl(VIDIOC_STREAMON) failed %d(%s)", errno, strerror(errno));
return false;
}
@@ -271,7 +342,8 @@ bool InnoMakerOV9281::getImage(Image &image)
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.) {
+ if (elapsedTime > 1000.)
+ {
// fprintf(stderr, "fps: %d, sec: %d\n", counter, curr.tv_sec);
fprintf(stderr,
"sum: %d,\tcorr: %d,\tval: %d\n",
@@ -298,12 +370,14 @@ bool InnoMakerOV9281::getImage(Image &image)
ret = ioctl(m_cam_fd, VIDIOC_DQBUF, &buffer);
- if (ret != 0) {
+ if (ret != 0)
+ {
DBG("ioctl(VIDIOC_DQBUF) failed %d(%s)", errno, strerror(errno));
return false;
}
- if (buffer.index < 0 || buffer.index >= BUFFER_COUNT) {
+ if (buffer.index < 0 || buffer.index >= BUFFER_COUNT)
+ {
DBG("invalid buffer index: %d", buffer.index);
return false;
}
@@ -313,12 +387,14 @@ bool InnoMakerOV9281::getImage(Image &image)
// TODO: fill
// image.counters.encoderPosition = RotaryEncoder::instance()->position();
image.counters.measurementCounter = buffer.sequence;
- image.counters.timestampUs = buffer.timestamp.tv_sec * 1000 * 1000 + buffer.timestamp.tv_usec;
+ image.counters.timestampUs = buffer.timestamp.tv_sec * 1000 * 1000 +
+ buffer.timestamp.tv_usec;
memcpy(image.data, video_buffer_ptr[buffer.index], img_size);
ret = ioctl(m_cam_fd, VIDIOC_QBUF, &buffer);
- if (ret != 0) {
+ if (ret != 0)
+ {
DBG("ioctl(VIDIOC_QBUF) failed %d(%s)", errno, strerror(errno));
return false;
}
diff --git a/src/camera/innomakerov9281.h b/src/camera/innomakerov9281.h
index 2c1fb7c..8c3a14e 100644
--- a/src/camera/innomakerov9281.h
+++ b/src/camera/innomakerov9281.h
@@ -24,12 +24,12 @@ public:
static std::vector<std::shared_ptr<ICamera>> search();
public:
- bool startStream();
+ bool startStream() override;
bool init();
- bool setExposureTimeMs(int value);
- bool setGain(int value);
+ bool setExposureTimeUs(int value) override;
+ bool setGain(int value) override;
bool getImage(Image &image);
diff --git a/src/camera/ov9281.h b/src/camera/ov9281.h
index 83a86ac..6014483 100644
--- a/src/camera/ov9281.h
+++ b/src/camera/ov9281.h
@@ -23,7 +23,7 @@ class Pixels;
class OV9281 : public QObject, public ICamera
{
- Q_OBJECT
+ // Q_OBJECT
public:
~OV9281();
@@ -37,6 +37,17 @@ public:
bool startStream() override;
void printControls();
+ bool setExposureTimeUs(int value) override
+ {
+ assert(false);
+ return false;
+ };
+ bool setGain(int value) override
+ {
+ assert(false);
+ return false;
+ };
+
// signals
public:
// TODO: image->pixels in separate thread