<div dir="ltr"><div dir="ltr">Hi Jean-Michel,<div><br></div><div>Thank you for your work.</div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, 23 Mar 2022 at 16:01, Jean-Michel Hautbois via libcamera-devel <<a href="mailto:libcamera-devel@lists.libcamera.org">libcamera-devel@lists.libcamera.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Now that the ancillary links are configured, we can use the CameraLens<br>
class and control the VCM through the IPA.<br>
For now, force a default value for the lens position, until the AF<br>
algorithm is introduced.<br>
<br>
Signed-off-by: Jean-Michel Hautbois <<a href="mailto:jeanmichel.hautbois@ideasonboard.com" target="_blank">jeanmichel.hautbois@ideasonboard.com</a>><br>
---<br>
v2: Change the need for lens control to be present<br>
---<br>
 src/ipa/raspberrypi/raspberrypi.cpp | 42 ++++++++++++++++++++++++++++-<br>
 1 file changed, 41 insertions(+), 1 deletion(-)<br>
<br>
diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp<br>
index cf4e6cab..ff302e37 100644<br>
--- a/src/ipa/raspberrypi/raspberrypi.cpp<br>
+++ b/src/ipa/raspberrypi/raspberrypi.cpp<br>
@@ -30,6 +30,7 @@<br>
<br>
 #include "libcamera/internal/mapped_framebuffer.h"<br>
<br>
+#include "af_status.h"<br>
 #include "agc_algorithm.hpp"<br>
 #include "agc_status.h"<br>
 #include "alsc_status.h"<br>
@@ -110,6 +111,7 @@ private:<br>
        void setMode(const IPACameraSensorInfo &sensorInfo);<br>
        bool validateSensorControls();<br>
        bool validateIspControls();<br>
+       bool validateLensControls();<br>
        void queueRequest(const ControlList &controls);<br>
        void returnEmbeddedBuffer(unsigned int bufferId);<br>
        void prepareISP(const ISPConfig &data);<br>
@@ -134,6 +136,7 @@ private:<br>
<br>
        ControlInfoMap sensorCtrls_;<br>
        ControlInfoMap ispCtrls_;<br>
+       ControlInfoMap lensCtrls_;<br>
        ControlList libcameraMetadata_;<br>
<br>
        /* Camera sensor params. */<br>
@@ -344,7 +347,7 @@ int IPARPi::configure(const IPACameraSensorInfo &sensorInfo,<br>
                      const IPAConfig &ipaConfig,<br>
                      ControlList *controls)<br>
 {<br>
-       if (entityControls.size() != 2) {<br>
+       if (entityControls.size() < 2) {<br>
                LOG(IPARPI, Error) << "No ISP or sensor controls found.";<br>
                return -1;<br>
        }<br>
@@ -352,6 +355,14 @@ int IPARPi::configure(const IPACameraSensorInfo &sensorInfo,<br>
        sensorCtrls_ = entityControls.at(0);<br>
        ispCtrls_ = entityControls.at(1);<br>
<br>
+       /* Lens may not be present, don't make it an hard assumption. */<br>
+       auto lensControl = entityControls.find(2);<br>
+       if (lensControl != entityControls.end()) {<br>
+               lensCtrls_ = lensControl->second;<br>
+               if (!validateLensControls())<br>
+                       LOG(IPARPI, Error) << "Lens control validation failed.";<br>
+       }<br>
+<br></blockquote><div><br></div><div>I wonder if we should be fetching the lens min/max/default values somewhere here to pass to the algorithm?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
        if (!validateSensorControls()) {<br>
                LOG(IPARPI, Error) << "Sensor control validation failed.";<br>
                return -1;<br>
@@ -362,6 +373,10 @@ int IPARPi::configure(const IPACameraSensorInfo &sensorInfo,<br>
                return -1;<br>
        }<br>
<br>
+       if (!validateLensControls()) {<br>
+               LOG(IPARPI, Error) << "Lens control validation failed.";<br>
+       }<br>
+<br></blockquote><div><br></div><div>This can be removed, the validation is done earlier.</div><div><br></div><div>Regards,</div><div>Naush</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
        maxSensorGainCode_ = sensorCtrls_.at(V4L2_CID_ANALOGUE_GAIN).max().get<int32_t>();<br>
<br>
        /* Setup a metadata ControlList to output metadata. */<br>
@@ -580,6 +595,23 @@ bool IPARPi::validateIspControls()<br>
        return true;<br>
 }<br>
<br>
+bool IPARPi::validateLensControls()<br>
+{<br>
+       static const uint32_t ctrls[] = {<br>
+               V4L2_CID_FOCUS_ABSOLUTE,<br>
+       };<br>
+<br>
+       for (auto c : ctrls) {<br>
+               if (lensCtrls_.find(c) == lensCtrls_.end()) {<br>
+                       LOG(IPARPI, Error) << "Unable to find lens control "<br>
+                                          << utils::hex(c);<br>
+                       return false;<br>
+               }<br>
+       }<br>
+<br>
+       return true;<br>
+}<br>
+<br>
 /*<br>
  * Converting between enums (used in the libcamera API) and the names that<br>
  * we use to identify different modes. Unfortunately, the conversion tables<br>
@@ -1068,6 +1100,14 @@ void IPARPi::processStats(unsigned int bufferId)<br>
<br>
                setDelayedControls.emit(ctrls);<br>
        }<br>
+<br>
+       struct AfStatus afStatus;<br>
+       if (rpiMetadata_.Get("af.status", afStatus) == 0) {<br>
+               ControlList lensCtrls(lensCtrls_);<br>
+               lensCtrls.set(V4L2_CID_FOCUS_ABSOLUTE,<br>
+                             static_cast<int32_t>(afStatus.focus));<br>
+               setLensControls.emit(lensCtrls);<br>
+       }<br>
 }<br>
<br>
 void IPARPi::applyAWB(const struct AwbStatus *awbStatus, ControlList &ctrls)<br>
-- <br>
2.32.0<br>
<br>
</blockquote></div></div>