Make imx462 not green
Use the isp in the rockpi to apply white balance gains to the image.
Signed-off-by: Ravago Jones <ravagojones@gmail.com>
Change-Id: I4a9b3bedf6da952fc6519aa7ed24514bcfc21a5e
diff --git a/y2023/vision/camera_reader.cc b/y2023/vision/camera_reader.cc
index fca5d53..a69caf3 100644
--- a/y2023/vision/camera_reader.cc
+++ b/y2023/vision/camera_reader.cc
@@ -1,3 +1,6 @@
+#include <linux/videodev2.h>
+#include <sys/ioctl.h>
+
#include "absl/strings/str_cat.h"
#include "absl/strings/str_split.h"
#include "aos/events/shm_event_loop.h"
@@ -5,9 +8,14 @@
#include "aos/realtime.h"
#include "frc971/vision/media_device.h"
#include "frc971/vision/v4l2_reader.h"
+#include "y2023/vision/rkisp1-config.h"
DEFINE_string(config, "aos_config.json", "Path to the config file to use.");
-DEFINE_bool(lowlight_camera, false, "Switch to use imx462 image sensor.");
+DEFINE_bool(lowlight_camera, true, "Switch to use imx462 image sensor.");
+
+DEFINE_double(red, 1.252, "Red gain");
+DEFINE_double(green, 1, "Green gain");
+DEFINE_double(blue, 1.96, "Blue gain");
namespace y2023 {
namespace vision {
@@ -96,12 +104,75 @@
if (FLAGS_lowlight_camera) {
v4l2_reader.SetGainExt(100);
v4l2_reader.SetVerticalBlanking(1000);
- v4l2_reader.SetExposure(50);
+ v4l2_reader.SetExposure(150);
} else {
v4l2_reader.SetGainExt(1000);
v4l2_reader.SetExposure(1000);
}
+ {
+ Entity *rkisp1_params = media_device->FindEntity("rkisp1_params");
+
+ LOG(INFO) << "Opening " << rkisp1_params->device();
+ aos::ScopedFD fd(open(rkisp1_params->device().c_str(), O_RDWR));
+ PCHECK(fd >= 0);
+
+ struct v4l2_capability capability;
+ memset(&capability, 0, sizeof(capability));
+ PCHECK(ioctl(fd.get(), VIDIOC_QUERYCAP, &capability) == 0);
+ CHECK(capability.device_caps & V4L2_CAP_META_OUTPUT);
+
+ // V4L2_META_FMT_RK_ISP1_PARAMS
+ // RK1P
+ uint32_t meta_params_format = (uint32_t)('R') | ((uint32_t)('K') << 8) |
+ ((uint32_t)('1') << 16) |
+ ((uint32_t)('P') << 24);
+ struct v4l2_format format;
+ std::memset(&format, 0, sizeof(format));
+ format.type = V4L2_BUF_TYPE_META_OUTPUT;
+
+ PCHECK(ioctl(fd.get(), VIDIOC_G_FMT, &format) == 0);
+ CHECK_EQ(format.fmt.meta.buffersize, 3048ul);
+ CHECK_EQ(format.fmt.meta.dataformat, meta_params_format);
+
+ struct v4l2_requestbuffers request;
+ memset(&request, 0, sizeof(request));
+ request.count = 1;
+ request.type = V4L2_BUF_TYPE_META_OUTPUT;
+ request.memory = V4L2_MEMORY_USERPTR;
+ PCHECK(ioctl(fd.get(), VIDIOC_REQBUFS, &request) == 0);
+
+ struct rkisp1_params_cfg configuration;
+ memset(&configuration, 0, sizeof(configuration));
+
+ configuration.module_cfg_update |= RKISP1_CIF_ISP_MODULE_AWB_GAIN;
+
+ configuration.others.awb_gain_config.gain_red = 256 * FLAGS_red;
+ configuration.others.awb_gain_config.gain_green_r = 256 * FLAGS_green;
+ configuration.others.awb_gain_config.gain_blue = 256 * FLAGS_blue;
+ configuration.others.awb_gain_config.gain_green_b = 256 * FLAGS_green;
+
+ // Enable the AWB gains
+ configuration.module_en_update |= RKISP1_CIF_ISP_MODULE_AWB_GAIN;
+ configuration.module_ens |= RKISP1_CIF_ISP_MODULE_AWB_GAIN;
+
+ struct v4l2_buffer buffer;
+ memset(&buffer, 0, sizeof(buffer));
+ buffer.memory = V4L2_MEMORY_USERPTR;
+ buffer.index = 0;
+ buffer.type = V4L2_BUF_TYPE_META_OUTPUT;
+ buffer.m.userptr = reinterpret_cast<uintptr_t>(&configuration);
+ buffer.length = format.fmt.meta.buffersize;
+
+ int type = V4L2_BUF_TYPE_META_OUTPUT;
+ PCHECK(ioctl(fd.get(), VIDIOC_STREAMON, &type) == 0);
+
+ PCHECK(ioctl(fd.get(), VIDIOC_QBUF, &buffer) == 0);
+ CHECK(buffer.flags & V4L2_BUF_FLAG_QUEUED);
+
+ PCHECK(ioctl(fd.get(), VIDIOC_DQBUF, &buffer) == 0);
+ }
+
event_loop.Run();
}