[libcamera-devel] [RFC PATCH 2/4] libcamera: pipeline: raspberrypi: Support the new AE controls
Paul Elder
paul.elder at ideasonboard.com
Tue Sep 28 09:49:57 CEST 2021
Add support for the new AE controls in the raspberrypi pipeline handler,
and in the IPA.
Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
---
This is very hacky. I wasn't sure what the best way was to plumb it into
the raspberrypi IPA as it was a bit hairy...
---
include/libcamera/ipa/raspberrypi.h | 3 +-
src/ipa/raspberrypi/controller/rpi/agc.cpp | 18 ++++++++-
src/ipa/raspberrypi/controller/rpi/agc.hpp | 5 +++
src/ipa/raspberrypi/raspberrypi.cpp | 42 ++++++++++++++++----
src/libcamera/pipeline/uvcvideo/uvcvideo.cpp | 17 ++++----
5 files changed, 67 insertions(+), 18 deletions(-)
diff --git a/include/libcamera/ipa/raspberrypi.h b/include/libcamera/ipa/raspberrypi.h
index 521eaecd..363ea038 100644
--- a/include/libcamera/ipa/raspberrypi.h
+++ b/include/libcamera/ipa/raspberrypi.h
@@ -28,8 +28,9 @@ namespace RPi {
* unsupported control is encountered.
*/
static const ControlInfoMap Controls({
- { &controls::AeEnable, ControlInfo(false, true) },
+ { &controls::ExposureTimeMode, ControlInfo(controls::ExposureTimeModeValues) },
{ &controls::ExposureTime, ControlInfo(0, 999999) },
+ { &controls::AnalogueGainMode, ControlInfo(controls::AnalogueGainModeValues) },
{ &controls::AnalogueGain, ControlInfo(1.0f, 32.0f) },
{ &controls::AeMeteringMode, ControlInfo(controls::AeMeteringModeValues) },
{ &controls::AeConstraintMode, ControlInfo(controls::AeConstraintModeValues) },
diff --git a/src/ipa/raspberrypi/controller/rpi/agc.cpp b/src/ipa/raspberrypi/controller/rpi/agc.cpp
index 289c1fce..b45ea454 100644
--- a/src/ipa/raspberrypi/controller/rpi/agc.cpp
+++ b/src/ipa/raspberrypi/controller/rpi/agc.cpp
@@ -203,14 +203,30 @@ bool Agc::IsPaused() const
}
void Agc::Pause()
+{
+}
+
+void Agc::Resume()
+{
+}
+
+void Agc::PauseExposure()
{
fixed_shutter_ = status_.shutter_time;
+}
+
+void Agc::PauseGain()
+{
fixed_analogue_gain_ = status_.analogue_gain;
}
-void Agc::Resume()
+void Agc::ResumeExposure()
{
fixed_shutter_ = 0s;
+}
+
+void Agc::ResumeGain()
+{
fixed_analogue_gain_ = 0;
}
diff --git a/src/ipa/raspberrypi/controller/rpi/agc.hpp b/src/ipa/raspberrypi/controller/rpi/agc.hpp
index 82063636..7ca3ca2f 100644
--- a/src/ipa/raspberrypi/controller/rpi/agc.hpp
+++ b/src/ipa/raspberrypi/controller/rpi/agc.hpp
@@ -92,6 +92,11 @@ public:
void Prepare(Metadata *image_metadata) override;
void Process(StatisticsPtr &stats, Metadata *image_metadata) override;
+ void PauseExposure();
+ void PauseGain();
+ void ResumeExposure();
+ void ResumeGain();
+
private:
void updateLockStatus(DeviceStatus const &device_status);
AgcConfig config_;
diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp
index 047123ab..99935515 100644
--- a/src/ipa/raspberrypi/raspberrypi.cpp
+++ b/src/ipa/raspberrypi/raspberrypi.cpp
@@ -53,6 +53,8 @@
#include "sharpen_algorithm.hpp"
#include "sharpen_status.h"
+#include "controller/rpi/agc.hpp"
+
namespace libcamera {
using namespace std::literals::chrono_literals;
@@ -478,7 +480,10 @@ void IPARPi::reportMetadata()
AgcStatus *agcStatus = rpiMetadata_.GetLocked<AgcStatus>("agc.status");
if (agcStatus) {
- libcameraMetadata_.set(controls::AeLocked, agcStatus->locked);
+ libcameraMetadata_.set(controls::AeState,
+ agcStatus->locked ?
+ controls::AeStateConverged :
+ controls::AeStateSearching);
libcameraMetadata_.set(controls::DigitalGain, agcStatus->digital_gain);
}
@@ -623,20 +628,22 @@ void IPARPi::queueRequest(const ControlList &controls)
<< " = " << ctrl.second.toString();
switch (ctrl.first) {
- case controls::AE_ENABLE: {
- RPiController::Algorithm *agc = controller_.GetAlgorithm("agc");
+ case controls::EXPOSURE_TIME_MODE: {
+ RPiController::Algorithm *algo = controller_.GetAlgorithm("agc");
+ RPiController::Agc *agc = reinterpret_cast<RPiController::Agc *>(algo);
if (!agc) {
LOG(IPARPI, Warning)
- << "Could not set AE_ENABLE - no AGC algorithm";
+ << "Could not set EXPOSURE_TIME_MODE - no AGC algorithm";
break;
}
- if (ctrl.second.get<bool>() == false)
- agc->Pause();
+ if (ctrl.second.get<int32_t>() == controls::ExposureTimeModeDisabled)
+ agc->PauseExposure();
else
- agc->Resume();
+ agc->ResumeExposure();
- libcameraMetadata_.set(controls::AeEnable, ctrl.second.get<bool>());
+ libcameraMetadata_.set(controls::ExposureTimeMode,
+ ctrl.second.get<int32_t>());
break;
}
@@ -656,6 +663,25 @@ void IPARPi::queueRequest(const ControlList &controls)
break;
}
+ case controls::ANALOGUE_GAIN_MODE: {
+ RPiController::Algorithm *algo = controller_.GetAlgorithm("agc");
+ RPiController::Agc *agc = reinterpret_cast<RPiController::Agc *>(algo);
+ if (!agc) {
+ LOG(IPARPI, Warning)
+ << "Could not set ANALOGUE_GAIN_MODE - no AGC algorithm";
+ break;
+ }
+
+ if (ctrl.second.get<int32_t>() == controls::AnalogueGainModeDisabled)
+ agc->PauseGain();
+ else
+ agc->ResumeGain();
+
+ libcameraMetadata_.set(controls::AnalogueGainMode,
+ ctrl.second.get<int32_t>());
+ break;
+ }
+
case controls::ANALOGUE_GAIN: {
RPiController::AgcAlgorithm *agc = dynamic_cast<RPiController::AgcAlgorithm *>(
controller_.GetAlgorithm("agc"));
diff --git a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
index c227d885..3a9c3b8d 100644
--- a/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
+++ b/src/libcamera/pipeline/uvcvideo/uvcvideo.cpp
@@ -309,25 +309,25 @@ int PipelineHandlerUVC::processControl(ControlList *controls, unsigned int id,
/* \todo Make this nicer. */
int32_t ivalue;
if (id == controls::ExposureTimeMode && exposureSet) {
- int32_t exposureMode = controls->get(V4L2_CID_EXPOSURE_AUTO);
- ivalue = value.get<int32_t>() == ExposureTimeModeAuto
+ int32_t exposureMode = controls->get(V4L2_CID_EXPOSURE_AUTO).get<int32_t>();
+ ivalue = value.get<int32_t>() == controls::ExposureTimeModeAuto
? (exposureMode == V4L2_EXPOSURE_SHUTTER_PRIORITY
? V4L2_EXPOSURE_AUTO
: V4L2_EXPOSURE_APERTURE_PRIORITY)
: V4L2_EXPOSURE_MANUAL;
} else if (id == controls::ExposureTimeMode && !exposureSet) {
- ivalue = value.get<int32_t>() == ExposureTimeModeAuto
+ ivalue = value.get<int32_t>() == controls::ExposureTimeModeAuto
? V4L2_EXPOSURE_APERTURE_PRIORITY
: V4L2_EXPOSURE_MANUAL;
} else if (id == controls::AnalogueGainMode && exposureSet) {
- int32_t exposureMode = controls->get(V4L2_CID_EXPOSURE_AUTO);
- ivalue = value.get<int32_t>() == AnalogueGainModeAuto
+ int32_t exposureMode = controls->get(V4L2_CID_EXPOSURE_AUTO).get<int32_t>();
+ ivalue = value.get<int32_t>() == controls::AnalogueGainModeAuto
? (exposureMode == V4L2_EXPOSURE_APERTURE_PRIORITY
? V4L2_EXPOSURE_AUTO
: V4L2_EXPOSURE_SHUTTER_PRIORITY)
: V4L2_EXPOSURE_MANUAL;
} else if (id == controls::AnalogueGainMode && !exposureSet) {
- ivalue = value.get<int32_t>() == AnalogueGainModeAuto
+ ivalue = value.get<int32_t>() == controls::AnalogueGainModeAuto
? V4L2_EXPOSURE_SHUTTER_PRIORITY
: V4L2_EXPOSURE_MANUAL;
}
@@ -636,8 +636,9 @@ void UVCCameraData::addControl(uint32_t cid, const ControlInfo &v4l2Info,
break;
case V4L2_CID_EXPOSURE_AUTO:
- info = ControlInfo{ { ExposureTimeModeAuto, ExposureTimeModeDisabled },
- ExposureTimeModeDisabled };
+ info = ControlInfo{ { controls::ExposureTimeModeAuto,
+ controls::ExposureTimeModeDisabled },
+ controls::ExposureTimeModeDisabled };
break;
case V4L2_CID_EXPOSURE_ABSOLUTE:
--
2.27.0
More information about the libcamera-devel
mailing list