diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/camera/icamera.h | 6 | ||||
| -rw-r--r-- | src/camera/innomakerov9281.cpp | 152 | ||||
| -rw-r--r-- | src/camera/innomakerov9281.h | 6 | ||||
| -rw-r--r-- | src/camera/ov9281.h | 13 |
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 |
