diff options
| author | Nikita Kostovsky <nikita@kostovsky.me> | 2025-11-11 14:55:09 +0100 |
|---|---|---|
| committer | Nikita Kostovsky <nikita@kostovsky.me> | 2025-11-11 14:55:09 +0100 |
| commit | fac69ff02f36e45d49da832c6bf246167d1025a6 (patch) | |
| tree | 4fd412200df3361ead604c3e77a089508bb7dd4b /src/main.cpp | |
| parent | 7bc77048d2bac80b675dbc0270a1a83559cb4b0f (diff) | |
works on radxa zero 3e, 420 fps
Diffstat (limited to 'src/main.cpp')
| -rw-r--r-- | src/main.cpp | 189 |
1 files changed, 163 insertions, 26 deletions
diff --git a/src/main.cpp b/src/main.cpp index bc0c00b..2ec6c0c 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,10 +1,13 @@ #include <chrono> #include <csignal> #include <errno.h> +#include <fcntl.h> #include <fstream> #include <iostream> #include <iterator> +#include <linux/videodev2.h> #include <string.h> +#include <sys/ioctl.h> #include <sys/mman.h> #include <thread> @@ -63,7 +66,7 @@ requested_params_t requested_params; namespace { // std::shared_ptr<Image> img; -Image *img = nullptr; +// Image *img = nullptr; Pixels pixels; std::vector<Pixels> calibrationPixels; QMutex calibrationPixelsMutex; @@ -100,18 +103,18 @@ auto printPixels = [](const auto& pixels) { }; // void onNewImage(std::shared_ptr<Image> image) -void onNewImage(Image &image) -{ - // std::cout << __func__ << std::endl << std::flush; +// void onNewImage(Image &image) +// { +// // std::cout << __func__ << std::endl << std::flush; - // if (!image) - // { - // qDebug() << __func__ << "no image"; - // return; - // } +// // if (!image) +// // { +// // qDebug() << __func__ << "no image"; +// // return; +// // } - ::img = ℑ -} +// ::img = ℑ +// } void onNewPixels(std::shared_ptr<Pixels> pixels) { @@ -139,6 +142,8 @@ void onNewPixels(std::shared_ptr<Pixels> pixels) bool initLaser(); +bool initCam(); + int main(int argc, char* argv[]) { auto sigHandler = [](int s) { @@ -148,6 +153,12 @@ int main(int argc, char* argv[]) // qApp->quit(); }; + // if (!initCam()) { + // return EXIT_FAILURE; + // } + + // return EXIT_SUCCESS; + // for (int i = 2000; i >= 0; i -= 50) { // for (int i = 0; i < 2000; i += 50) { // if (!veye::imx287m::test(i)) { @@ -415,7 +426,7 @@ int main(int argc, char* argv[]) std::cout << "connect everything" << std::endl; camera->newPixels.connect(&onNewPixels); // camera->newImage.connect(&onNewImage); - camera->newImageCallback = &onNewImage; + // camera->newImageCallback = &onNewImage; camera->newPixelsCallback = &onNewPixels; for (auto& i : initializers) @@ -444,16 +455,18 @@ int main(int argc, char* argv[]) return QHttpServerResponse::StatusCode::ServiceUnavailable; } - Image img; + static Image img; // yeaah - ::img = &img; + // ::img = &img; if (!cam->getImage(img)) { qDebug() << "cannot get image"; return QHttpServerResponse::StatusCode::ServiceUnavailable; } - pgm_save(::img); - // save = false; + // std::cout << "http: got image" << std::endl << std::flush; + // pgm_save(::img); + pgm_save(&img); std::lock_guard<std::mutex> lg(pgm_image_mtx); + // save = false; // qDebug() << "mutex locked"; // qDebug() << "image saved to array"; return QHttpServerResponse{QByteArray((const char *) pgm_image, pgm_image_size), @@ -478,7 +491,7 @@ int main(int argc, char* argv[]) Image img; // yeaah - ::img = &img; + // ::img = &img; if (!cam->getImage(img)) { qDebug() << "cannot get image"; return QHttpServerResponse::StatusCode::ServiceUnavailable; @@ -486,7 +499,7 @@ int main(int argc, char* argv[]) ::pixels = std::move(img.pixels()); - std::lock_guard<std::mutex> lg(pgm_image_mtx); + // std::lock_guard<std::mutex> lg(pgm_image_mtx); // qt json does not allow to limit double precision @@ -525,11 +538,11 @@ int main(int argc, char* argv[]) const auto result = QJsonDocument(json).toJson(); // qDebug() << "pixels answer size is" << result.size(); - static bool done{false}; - if (!done) { - qDebug().noquote() << result; - done = true; - } + // static bool done{false}; + // if (!done) { + // qDebug().noquote() << result; + // done = true; + // } { rapidjson::Document jd; @@ -551,8 +564,9 @@ int main(int argc, char* argv[]) writer.SetMaxDecimalPlaces(2); jd.Accept(writer); QString res{(const char *) buffer.GetString()}; - qDebug() << "size:" << res.size(); - // qDebug().noquote() << res; + // qDebug() << "size:" << res.size(); + // qDebug().noquote() << "ret pix"; + return QHttpServerResponse{res}; } @@ -575,7 +589,7 @@ int main(int argc, char* argv[]) // std::cout << buffer.GetString() << "\n"; // } - qDebug() << "size:" << result.size(); + // qDebug() << "size:" << result.size(); return QHttpServerResponse(result); }); @@ -912,3 +926,126 @@ bool initLaser() return true; } + +bool initCam() +{ + const v4l2_memory memtype = V4L2_MEMORY_MMAP; + v4l2_buf_type type = (enum v4l2_buf_type) - 1; + const char *devname{"/dev/video0"}; + int fd{open(devname, O_RDWR)}; + + if (fd < 0) { + printf("Error opening device %s: %s (%d).\n", devname, strerror(errno), errno); + fflush(stdout); + return false; + } + + std::cout << devname << ": opened" << std::endl; + + v4l2_capability cap; + memset(&cap, 0, sizeof cap); + const auto ret = ioctl(fd, VIDIOC_QUERYCAP, &cap); + if (ret < 0) { + printf("cannot query cap for %s: %s (%d).\n", devname, strerror(errno), errno); + fflush(stdout); + return false; + } + + std::cout << devname << ": got caps" << std::endl; + + const auto caps = cap.capabilities & V4L2_CAP_DEVICE_CAPS ? cap.device_caps : cap.capabilities; + const bool has_video = caps + & (V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_CAPTURE + | V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_VIDEO_OUTPUT); + const bool has_meta = caps & (V4L2_CAP_META_CAPTURE | V4L2_CAP_META_OUTPUT); + const bool has_capture = caps + & (V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_CAPTURE + | V4L2_CAP_META_CAPTURE); + const bool has_output = caps + & (V4L2_CAP_VIDEO_OUTPUT_MPLANE | V4L2_CAP_VIDEO_OUTPUT + | V4L2_CAP_META_OUTPUT); + const bool has_mplane = caps & (V4L2_CAP_VIDEO_CAPTURE_MPLANE | V4L2_CAP_VIDEO_OUTPUT_MPLANE); + + printf("Device `%s' on `%s' (driver '%s') supports%s%s%s%s %s mplanes.\n", + cap.card, + cap.bus_info, + cap.driver, + has_video ? " video," : "", + has_meta ? " meta-data," : "", + has_capture ? " capture," : "", + has_output ? " output," : "", + has_mplane ? "with" : "without"); + + const auto buf_type = [caps, devname]() -> int { + if (caps & V4L2_CAP_VIDEO_CAPTURE_MPLANE) { + std::cout << devname << ": buf_type: V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE" << std::endl; + return V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; + } else if (caps & V4L2_CAP_VIDEO_OUTPUT_MPLANE) { + std::cout << devname << ": buf_type: V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE" << std::endl; + return V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; + } else if (caps & V4L2_CAP_VIDEO_CAPTURE) { + std::cout << devname << ": buf_type: V4L2_BUF_TYPE_VIDEO_CAPTURE" << std::endl; + return V4L2_BUF_TYPE_VIDEO_CAPTURE; + } else if (caps & V4L2_CAP_VIDEO_OUTPUT) { + std::cout << devname << ": buf_type: V4L2_BUF_TYPE_VIDEO_OUTPUT" << std::endl; + return V4L2_BUF_TYPE_VIDEO_OUTPUT; + } else if (caps & V4L2_CAP_META_CAPTURE) { + std::cout << devname << ": buf_type: V4L2_BUF_TYPE_META_CAPTURE" << std::endl; + return V4L2_BUF_TYPE_META_CAPTURE; + } else if (caps & V4L2_CAP_META_OUTPUT) { + std::cout << devname << ": buf_type: V4L2_BUF_TYPE_META_OUTPUT" << std::endl; + return V4L2_BUF_TYPE_META_OUTPUT; + } else { + printf("Device supports neither capture nor output.\n"); + return -EINVAL; + } + }(); + + if (buf_type < 0) { + return false; + } + + if (false) { + v4l2_format fmt; + memset(&fmt, 0, sizeof fmt); + fmt.type = buf_type; + + if (ioctl(fd, VIDIOC_G_FMT, &fmt) < 0) { + printf("Unable to get format: %s (%d).\n", strerror(errno), errno); + + return false; + } + + const auto width = fmt.fmt.pix_mp.width; + const auto height = fmt.fmt.pix_mp.height; + const auto num_planes = fmt.fmt.pix_mp.num_planes; + struct v4l2_plane_pix_format plane_fmt[VIDEO_MAX_PLANES] = {0}; + + printf("Video format: (%08x) %ux%u field %d, %u planes: \n", + fmt.fmt.pix_mp.pixelformat, + fmt.fmt.pix_mp.width, + fmt.fmt.pix_mp.height, + fmt.fmt.pix_mp.field, + fmt.fmt.pix_mp.num_planes); + + for (int i = 0; i < fmt.fmt.pix_mp.num_planes; i++) { + plane_fmt[i].bytesperline = fmt.fmt.pix_mp.plane_fmt[i].bytesperline; + plane_fmt[i].sizeimage = fmt.fmt.pix_mp.plane_fmt[i].bytesperline + ? fmt.fmt.pix_mp.plane_fmt[i].sizeimage + : 0; + + printf(" * Stride %u, buffer size %u\n", + fmt.fmt.pix_mp.plane_fmt[i].bytesperline, + fmt.fmt.pix_mp.plane_fmt[i].sizeimage); + } + } + + unsigned int padding = 0; + unsigned int nbufs = 8; + + // if () + + close(fd); + + return true; +} |
