diff options
| -rw-r--r-- | src/camera/veye_i2c.cpp | 53 | ||||
| -rw-r--r-- | src/camera/veye_i2c.h | 19 | ||||
| -rw-r--r-- | src/camera/veyeimx287m.cpp | 94 | ||||
| -rw-r--r-- | src/camera/veyeimx287m.h | 25 |
4 files changed, 123 insertions, 68 deletions
diff --git a/src/camera/veye_i2c.cpp b/src/camera/veye_i2c.cpp index 9d04d9b..c34da51 100644 --- a/src/camera/veye_i2c.cpp +++ b/src/camera/veye_i2c.cpp @@ -15,15 +15,17 @@ bool veye::imx287m::i2cRead(int fd, uint8_t i2c_addr, uint16_t reg, uint32_t &value) { int err; - int i = 0; - uint8_t buf[2] = {reg >> 8, reg & 0xff}; + uint8_t bufin[2] = {reg >> 8, reg & 0xff}; uint8_t bufout[4] = {0}; struct i2c_msg msgs[2] = { - {.addr = i2c_addr, - .flags = 0, - .len = 2, - // .buf = (uint8_t *) (®), - .buf = buf}, + { + // + .addr = i2c_addr, + .flags = 0, + .len = 2, + .buf = bufin + // + }, { .addr = i2c_addr, .flags = I2C_M_RD, @@ -39,7 +41,7 @@ bool veye::imx287m::i2cRead(int fd, uint8_t i2c_addr, uint16_t reg, uint32_t &va err = ioctl(fd, I2C_RDWR, &msgset); //printf("Read i2c addr %02X\n", i2c_addr); if (err != msgset.nmsgs) { - std::cerr << "Read i2c err " << err << std::endl; + std::cerr << "read i2c err " << err << std::endl; return false; } @@ -51,7 +53,8 @@ bool veye::imx287m::i2cRead(int fd, uint8_t i2c_addr, uint16_t reg, uint32_t &va bool veye::imx287m::test(uint32_t value) { - const std::string i2cDevName{"/dev/i2c-10"}; + // const std::string i2cDevName{"/dev/i2c-10"}; + const std::string i2cDevName{"/dev/i2c-2"}; constexpr uint32_t i2cDevAddr{0x3b}; int fd = open(i2cDevName.c_str(), O_RDWR); @@ -104,3 +107,35 @@ bool veye::imx287m::i2cWrite(int fd, uint16_t reg, const uint32_t value) return true; } + +veye::imx287m::i2c::i2c(const std::string &name, const int address) + : m_name{name} + , m_address{address} +{} + +veye::imx287m::i2c::~i2c() +{ + if (m_fd > 0) { + close(m_fd); + } +} + +bool veye::imx287m::i2c::open() +{ + m_fd = ::open(m_name.c_str(), O_RDWR); + + if (!m_fd) { + std::cerr << "cannot open i2c device " << m_name << ", error: " << strerror(errno) + << std::endl; + return false; + } + + if (ioctl(m_fd, I2C_SLAVE_FORCE, m_address) < 0) { + std::cerr << "cannot set i2c slave. dev: " << m_name << ", addr: " << m_address + << ", error: " << strerror(errno) << std::endl; + + return false; + } + + return true; +} diff --git a/src/camera/veye_i2c.h b/src/camera/veye_i2c.h index 1638976..001d483 100644 --- a/src/camera/veye_i2c.h +++ b/src/camera/veye_i2c.h @@ -1,9 +1,28 @@ #pragma once #include <cstdint> +#include <string> namespace veye { namespace imx287m { +class i2c +{ +public: + i2c(const std::string &name = "/dev/i2c-2", const int address = 0x3b); + ~i2c(); + +public: + bool read(uint16_t reg, uint32_t &value); + bool write(uint16_t reg, const uint32_t value); + +private: + bool open(); + +private: + int m_fd{-1}; + std::string m_name; + int m_address{-1}; +}; bool i2cRead(int fd, uint8_t i2c_addr, uint16_t reg, uint32_t &value); bool i2cWrite(int fd, uint16_t reg, const uint32_t value); diff --git a/src/camera/veyeimx287m.cpp b/src/camera/veyeimx287m.cpp index 16ab344..3f3a9e6 100644 --- a/src/camera/veyeimx287m.cpp +++ b/src/camera/veyeimx287m.cpp @@ -16,7 +16,11 @@ #include <QElapsedTimer> +<<<<<<< Updated upstream // orpheus +======= +#include "camera/veye_i2c.h" +>>>>>>> Stashed changes #include "constants.h" #include "httpservice.h" #include "imagealgos.h" @@ -316,8 +320,31 @@ bool VeyeIMX287m::init() return true; } +bool VeyeIMX287m::setExposureTime(const std::chrono::microseconds us) +{ + const std::string i2c_dev{"/dev/i2c-2"}; + const auto address = 0x3b; + const auto metime_reg = 0xc10; + const auto val = us.count(); + + const int fd = open(i2c_dev.c_str(), O_RDWR); + + if (!fd) { + std::cerr << "cannot open i2c dev: " << i2c_dev << ", errno: " << errno << " (" + << strerror(errno) << ")" << std::endl; + return false; + } + + return true; +} + bool VeyeIMX287m::setExposureTimeUs(int valueUs) { + std::cout << "AAAAAAAAAAAAAAAAAAAAAAAAAAAAA: " << __func__ << ": " << valueUs << std::endl; + const std::string i2c_dev{"/dev/i2c-2"}; + const auto address = 0x3b; + const auto metime_reg = 0xc10; + //return true; std::cout << __func__ << ": " << V4L2_CID_EXPOSURE << " - " << valueUs << std::endl << std::flush; @@ -373,6 +400,8 @@ bool VeyeIMX287m::setSomething(int value) bool VeyeIMX287m::setCamParam(unsigned int v4l2controlId, int value) { + veye::imx287m::test(value); + std::cout << "radxa: skip setCamParam" << std::endl; return true; @@ -625,6 +654,7 @@ bool VeyeIMX287m::initCam() return true; } +<<<<<<< Updated upstream bool VeyeIMX287m::initHttpServer() { m_httpServer = std::make_shared<HttpServer>(this); @@ -647,47 +677,30 @@ void VeyeIMX287m::dequeueFrameLoop(std::stop_token stopToken) // std::cout << "VeyeIMX287m: stream interruption requested" << std::endl; } +======= +>>>>>>> Stashed changes void VeyeIMX287m::calcFrameLoop(std::stop_token stopToken) { QElapsedTimer t; while (!stopToken.stop_requested()) { - size_t bufferIdx{}; + size_t bufferIdx{std::numeric_limits<size_t>::max()}; if (!dequeueImageBuffer(bufferIdx)) { - std::cout << "AAAAAAAAAAAAAAAAAA" << std::endl; continue; } - // std::lock_guard img_lock{m_imageMutexes[bufferIdx]}; + std::lock_guard lock{m_imageMutexes[bufferIdx]}; + auto &image = m_images[bufferIdx]; { t.start(); - // auto &src = *(Image::data_t *) m_videoBuffers[bufferIdx]; + auto &src = *(Image::radxa_data_t *) m_videoBuffers[bufferIdx]; auto &dst = image.data; Image::copy(dst, src); - // #pragma omp parallel for num_threads(4) - // for (size_t i = 0; i < img_height; ++i) { - // memcpy(dst[i].data(), src[i].data(), img_width); - // } - - // for (std::tuple<Image::row_t, Image::row_t> dst_src : std::views::zip()) - - // auto &dst = *(Image::data_t *) m_videoBuffers[bufferIdx]; - // std::transform(std::execution::unseq, - // src.begin(), - // src.end(), - // dst.begin(), - // src.begin(), - // [](auto &srcRow, auto &dstRow) -> Image::row_t { - // // memcpy(dstRow.data(), srcRow.data(), img_width); - // return dstRow; - // // return Image::row_t(dst.begin(), dst.begin() + img_width); - // }); - // memcpy(&image.data, m_videoBuffers[bufferIdx], radxa_raw_img_size); get_elapsed_ns += t.nsecsElapsed(); } @@ -756,26 +769,17 @@ bool VeyeIMX287m::dequeueImageBuffer(size_t &imageIndex) buf.length = VIDEO_MAX_PLANES; buf.m.planes = planes; static uint16_t requestIdx{0}; - // buffer.index = BUFFER_COUNT; - const auto tmpIdx = requestIdx++ % BUFFER_COUNT; buf.index = requestIdx++ % BUFFER_COUNT; { - QElapsedTimer t; - t.start(); - - auto oldIdx = buf.index; // m_bufferMutexes[buffer.index].lock(); { std::lock_guard<std::mutex> lock(m_camMtx); + QElapsedTimer t; + t.start(); ret = ioctl(m_cam_fd, VIDIOC_DQBUF, &buf); - } - - // m_bufferMutexes[buffer.index].unlock(); - auto newIdx = buf.index; - - if (oldIdx != newIdx) { - // std::cout << "AAAAAAAAAAAAAA " << oldIdx << ' ' << newIdx << std::endl; + ++counter; + dq_elapsed_ns += t.nsecsElapsed(); } if (ret != 0) { @@ -788,16 +792,9 @@ bool VeyeIMX287m::dequeueImageBuffer(size_t &imageIndex) std::cerr << "invalid buffer index: " << buf.index << std::endl; 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 = buf.index; - // std::cout << "index: " << imageIndex << '\t' << tmpIdx << std::endl; auto &image = m_images[buf.index]; image.height = img_height; image.width = img_width; @@ -830,24 +827,19 @@ bool VeyeIMX287m::getImage(Image &image) size_t bufferIdx{}; if (!dequeueImageBuffer(bufferIdx)) { - std::cout << "AAAAAAAAAAAAAAAAAA" << std::endl; return false; } + // TODO: remove this bullshit. return ptr to image or copy image metainfo + // only, then copy data image = std::move(m_images[bufferIdx]); { QElapsedTimer t; t.start(); - // memcpy(&image.data, m_videoBuffers[bufferIdx], img_size); + std::lock_guard lock{m_imageMutexes[bufferIdx]}; auto &src = *(Image::radxa_data_t *) m_videoBuffers[bufferIdx]; auto &dst = image.data; Image::copy(dst, src); - - // #pragma omp parallel for num_threads(4) - // for (size_t i = 0; i < img_height; ++i) { - // memcpy(dst[i].data(), src[i].data(), img_width); - // } - // memcpy(&image.data, buffers[bufferIdx].mem[0], img_size); get_elapsed_ns += t.nsecsElapsed(); } diff --git a/src/camera/veyeimx287m.h b/src/camera/veyeimx287m.h index 5afc84b..7d7e2c6 100644 --- a/src/camera/veyeimx287m.h +++ b/src/camera/veyeimx287m.h @@ -31,6 +31,7 @@ public: bool init(); + bool setExposureTime(const std::chrono::microseconds us); bool setExposureTimeUs(int value) override; bool setGain(int value) override; @@ -38,14 +39,14 @@ public: 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; + /*! + * \brief processedCounter - count of images processed in current second. + * Used for performance measurement and bottlenecks analysing + */ uint32_t processedCounter{0}; private: @@ -55,18 +56,26 @@ private: bool initCam(); bool initHttpServer(); - void dequeueFrameLoop(std::stop_token stopToken); void calcFrameLoop(std::stop_token stopToken); private: + /*! + * \brief m_cam_fd - camera file descriptor + */ int m_cam_fd{-1}; static constexpr uint8_t BUFFER_COUNT{16}; - struct v4l2_plane planes[VIDEO_MAX_PLANES]; - std::array<std::mutex, BUFFER_COUNT> m_imageMutexes; std::array<Image, BUFFER_COUNT> m_images; - std::array<std::mutex, BUFFER_COUNT> m_bufferMutexes; + /*! + * \brief m_imageMutexes - lock while processing image from m_images + */ + std::array<std::mutex, BUFFER_COUNT> m_imageMutexes; + /*! + * \todo copy image right after dequeue to avoid situation with ioctl writing + * to m_videoBuffers[i] which is being copied to m_images[i]. In theory, it + * should not overlap if BUFFER_COUNT > theads count + */ std::array<uint8_t *, BUFFER_COUNT> m_videoBuffers; struct buffer |
