summaryrefslogtreecommitdiff
path: root/src/main.cpp
diff options
context:
space:
mode:
authorNikita Kostovsky <nikita@kostovsky.me>2025-11-11 14:55:09 +0100
committerNikita Kostovsky <nikita@kostovsky.me>2025-11-11 14:55:09 +0100
commitfac69ff02f36e45d49da832c6bf246167d1025a6 (patch)
tree4fd412200df3361ead604c3e77a089508bb7dd4b /src/main.cpp
parent7bc77048d2bac80b675dbc0270a1a83559cb4b0f (diff)
works on radxa zero 3e, 420 fps
Diffstat (limited to 'src/main.cpp')
-rw-r--r--src/main.cpp189
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 = &image;
-}
+// ::img = &image;
+// }
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;
+}