[libcamera-devel,v4,1/2] ipa: rpi: Implement HDR control
diff mbox series

Message ID 20240109102547.2762-2-david.plowman@raspberrypi.com
State Accepted
Headers show
Series
  • HDR for Raspberry Pi
Related show

Commit Message

David Plowman Jan. 9, 2024, 10:25 a.m. UTC
Sufficient plumbing is added so that the HDR mode control can be used
to engage HDR modes on platforms that support them. On the vc4
platform, this allows multi-channel AGC to run, though there is no
image merging.

Signed-off-by: David Plowman <david.plowman@raspberrypi.com>
---
 src/ipa/rpi/common/ipa_base.cpp | 49 +++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)

Comments

Kieran Bingham Jan. 9, 2024, 1:39 p.m. UTC | #1
Quoting David Plowman via libcamera-devel (2024-01-09 10:25:46)
> Sufficient plumbing is added so that the HDR mode control can be used
> to engage HDR modes on platforms that support them. On the vc4
> platform, this allows multi-channel AGC to run, though there is no
> image merging.
> 
> Signed-off-by: David Plowman <david.plowman@raspberrypi.com>

https://patchwork.libcamera.org/patch/19057/ had an RB tag from Naush.

Does it still apply here?

Naush - Can you confirm you're happy with this patch please?

--
Kieran


> ---
>  src/ipa/rpi/common/ipa_base.cpp | 49 +++++++++++++++++++++++++++++++++
>  1 file changed, 49 insertions(+)
> 
> diff --git a/src/ipa/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp
> index 6ec91575..632b8d2f 100644
> --- a/src/ipa/rpi/common/ipa_base.cpp
> +++ b/src/ipa/rpi/common/ipa_base.cpp
> @@ -24,6 +24,8 @@
>  #include "controller/ccm_status.h"
>  #include "controller/contrast_algorithm.h"
>  #include "controller/denoise_algorithm.h"
> +#include "controller/hdr_algorithm.h"
> +#include "controller/hdr_status.h"
>  #include "controller/lux_status.h"
>  #include "controller/sharpen_algorithm.h"
>  #include "controller/statistics.h"
> @@ -67,6 +69,7 @@ const ControlInfoMap::Map ipaControls{
>         { &controls::AeFlickerPeriod, ControlInfo(100, 1000000) },
>         { &controls::Brightness, ControlInfo(-1.0f, 1.0f, 0.0f) },
>         { &controls::Contrast, ControlInfo(0.0f, 32.0f, 1.0f) },
> +       { &controls::HdrMode, ControlInfo(controls::HdrModeValues) },
>         { &controls::Sharpness, ControlInfo(0.0f, 16.0f, 1.0f) },
>         { &controls::ScalerCrop, ControlInfo(Rectangle{}, Rectangle(65535, 65535, 65535, 65535), Rectangle{}) },
>         { &controls::FrameDurationLimits, ControlInfo(INT64_C(33333), INT64_C(120000)) },
> @@ -688,9 +691,17 @@ static const std::map<int32_t, RPiController::AfAlgorithm::AfPause> AfPauseTable
>         { controls::AfPauseResume, RPiController::AfAlgorithm::AfPauseResume },
>  };
>  
> +static const std::map<int32_t, std::string> HdrModeTable = {
> +       { controls::HdrModeOff, "Off" },
> +       { controls::HdrModeMultiExposure, "MultiExposure" },
> +       { controls::HdrModeSingleExposure, "SingleExposure" },
> +};
> +
>  void IpaBase::applyControls(const ControlList &controls)
>  {
> +       using RPiController::AgcAlgorithm;
>         using RPiController::AfAlgorithm;
> +       using RPiController::HdrAlgorithm;
>  
>         /* Clear the return metadata buffer. */
>         libcameraMetadata_.clear();
> @@ -1162,6 +1173,34 @@ void IpaBase::applyControls(const ControlList &controls)
>                         break;
>                 }
>  
> +               case controls::HDR_MODE: {
> +                       HdrAlgorithm *hdr = dynamic_cast<HdrAlgorithm *>(controller_.getAlgorithm("hdr"));
> +                       if (!hdr) {
> +                               LOG(IPARPI, Warning) << "No HDR algorithm available";
> +                               break;
> +                       }
> +
> +                       auto mode = HdrModeTable.find(ctrl.second.get<int32_t>());
> +                       if (mode == HdrModeTable.end()) {
> +                               LOG(IPARPI, Warning) << "Unrecognised HDR mode";
> +                               break;
> +                       }
> +
> +                       AgcAlgorithm *agc = dynamic_cast<AgcAlgorithm *>(controller_.getAlgorithm("agc"));
> +                       if (!agc) {
> +                               LOG(IPARPI, Warning) << "HDR requires an AGC algorithm";
> +                               break;
> +                       }
> +
> +                       if (hdr->setMode(mode->second) == 0)
> +                               agc->setActiveChannels(hdr->getChannels());
> +                       else
> +                               LOG(IPARPI, Warning)
> +                                       << "HDR mode " << mode->second << " not supported";
> +
> +                       break;
> +               }
> +
>                 default:
>                         LOG(IPARPI, Warning)
>                                 << "Ctrl " << controls::controls.at(ctrl.first)->name()
> @@ -1309,6 +1348,16 @@ void IpaBase::reportMetadata(unsigned int ipaContext)
>                 libcameraMetadata_.set(controls::AfPauseState, p);
>         }
>  
> +       const HdrStatus *hdrStatus = rpiMetadata.getLocked<HdrStatus>("hdr.status");
> +       if (hdrStatus) {
> +               if (hdrStatus->channel == "short")
> +                       libcameraMetadata_.set(controls::HdrChannel, controls::HdrChannelShort);
> +               else if (hdrStatus->channel == "long")
> +                       libcameraMetadata_.set(controls::HdrChannel, controls::HdrChannelLong);
> +               else
> +                       libcameraMetadata_.set(controls::HdrChannel, controls::HdrChannelNone);
> +       }
> +
>         metadataReady.emit(libcameraMetadata_);
>  }
>  
> -- 
> 2.30.2
>
Naushir Patuck Jan. 9, 2024, 1:47 p.m. UTC | #2
Hi David,

Thanks for the update.

On Tue, 9 Jan 2024 at 10:25, David Plowman via libcamera-devel
<libcamera-devel@lists.libcamera.org> wrote:
>
> Sufficient plumbing is added so that the HDR mode control can be used
> to engage HDR modes on platforms that support them. On the vc4
> platform, this allows multi-channel AGC to run, though there is no
> image merging.
>
> Signed-off-by: David Plowman <david.plowman@raspberrypi.com>

Reviewed-by: Naushir Patuck <naush@raspberrypi.com>

> ---
>  src/ipa/rpi/common/ipa_base.cpp | 49 +++++++++++++++++++++++++++++++++
>  1 file changed, 49 insertions(+)
>
> diff --git a/src/ipa/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp
> index 6ec91575..632b8d2f 100644
> --- a/src/ipa/rpi/common/ipa_base.cpp
> +++ b/src/ipa/rpi/common/ipa_base.cpp
> @@ -24,6 +24,8 @@
>  #include "controller/ccm_status.h"
>  #include "controller/contrast_algorithm.h"
>  #include "controller/denoise_algorithm.h"
> +#include "controller/hdr_algorithm.h"
> +#include "controller/hdr_status.h"
>  #include "controller/lux_status.h"
>  #include "controller/sharpen_algorithm.h"
>  #include "controller/statistics.h"
> @@ -67,6 +69,7 @@ const ControlInfoMap::Map ipaControls{
>         { &controls::AeFlickerPeriod, ControlInfo(100, 1000000) },
>         { &controls::Brightness, ControlInfo(-1.0f, 1.0f, 0.0f) },
>         { &controls::Contrast, ControlInfo(0.0f, 32.0f, 1.0f) },
> +       { &controls::HdrMode, ControlInfo(controls::HdrModeValues) },
>         { &controls::Sharpness, ControlInfo(0.0f, 16.0f, 1.0f) },
>         { &controls::ScalerCrop, ControlInfo(Rectangle{}, Rectangle(65535, 65535, 65535, 65535), Rectangle{}) },
>         { &controls::FrameDurationLimits, ControlInfo(INT64_C(33333), INT64_C(120000)) },
> @@ -688,9 +691,17 @@ static const std::map<int32_t, RPiController::AfAlgorithm::AfPause> AfPauseTable
>         { controls::AfPauseResume, RPiController::AfAlgorithm::AfPauseResume },
>  };
>
> +static const std::map<int32_t, std::string> HdrModeTable = {
> +       { controls::HdrModeOff, "Off" },
> +       { controls::HdrModeMultiExposure, "MultiExposure" },
> +       { controls::HdrModeSingleExposure, "SingleExposure" },
> +};
> +
>  void IpaBase::applyControls(const ControlList &controls)
>  {
> +       using RPiController::AgcAlgorithm;
>         using RPiController::AfAlgorithm;
> +       using RPiController::HdrAlgorithm;
>
>         /* Clear the return metadata buffer. */
>         libcameraMetadata_.clear();
> @@ -1162,6 +1173,34 @@ void IpaBase::applyControls(const ControlList &controls)
>                         break;
>                 }
>
> +               case controls::HDR_MODE: {
> +                       HdrAlgorithm *hdr = dynamic_cast<HdrAlgorithm *>(controller_.getAlgorithm("hdr"));
> +                       if (!hdr) {
> +                               LOG(IPARPI, Warning) << "No HDR algorithm available";
> +                               break;
> +                       }
> +
> +                       auto mode = HdrModeTable.find(ctrl.second.get<int32_t>());
> +                       if (mode == HdrModeTable.end()) {
> +                               LOG(IPARPI, Warning) << "Unrecognised HDR mode";
> +                               break;
> +                       }
> +
> +                       AgcAlgorithm *agc = dynamic_cast<AgcAlgorithm *>(controller_.getAlgorithm("agc"));
> +                       if (!agc) {
> +                               LOG(IPARPI, Warning) << "HDR requires an AGC algorithm";
> +                               break;
> +                       }
> +
> +                       if (hdr->setMode(mode->second) == 0)
> +                               agc->setActiveChannels(hdr->getChannels());
> +                       else
> +                               LOG(IPARPI, Warning)
> +                                       << "HDR mode " << mode->second << " not supported";
> +
> +                       break;
> +               }
> +
>                 default:
>                         LOG(IPARPI, Warning)
>                                 << "Ctrl " << controls::controls.at(ctrl.first)->name()
> @@ -1309,6 +1348,16 @@ void IpaBase::reportMetadata(unsigned int ipaContext)
>                 libcameraMetadata_.set(controls::AfPauseState, p);
>         }
>
> +       const HdrStatus *hdrStatus = rpiMetadata.getLocked<HdrStatus>("hdr.status");
> +       if (hdrStatus) {
> +               if (hdrStatus->channel == "short")
> +                       libcameraMetadata_.set(controls::HdrChannel, controls::HdrChannelShort);
> +               else if (hdrStatus->channel == "long")
> +                       libcameraMetadata_.set(controls::HdrChannel, controls::HdrChannelLong);
> +               else
> +                       libcameraMetadata_.set(controls::HdrChannel, controls::HdrChannelNone);
> +       }
> +
>         metadataReady.emit(libcameraMetadata_);
>  }
>
> --
> 2.30.2
>

Patch
diff mbox series

diff --git a/src/ipa/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp
index 6ec91575..632b8d2f 100644
--- a/src/ipa/rpi/common/ipa_base.cpp
+++ b/src/ipa/rpi/common/ipa_base.cpp
@@ -24,6 +24,8 @@ 
 #include "controller/ccm_status.h"
 #include "controller/contrast_algorithm.h"
 #include "controller/denoise_algorithm.h"
+#include "controller/hdr_algorithm.h"
+#include "controller/hdr_status.h"
 #include "controller/lux_status.h"
 #include "controller/sharpen_algorithm.h"
 #include "controller/statistics.h"
@@ -67,6 +69,7 @@  const ControlInfoMap::Map ipaControls{
 	{ &controls::AeFlickerPeriod, ControlInfo(100, 1000000) },
 	{ &controls::Brightness, ControlInfo(-1.0f, 1.0f, 0.0f) },
 	{ &controls::Contrast, ControlInfo(0.0f, 32.0f, 1.0f) },
+	{ &controls::HdrMode, ControlInfo(controls::HdrModeValues) },
 	{ &controls::Sharpness, ControlInfo(0.0f, 16.0f, 1.0f) },
 	{ &controls::ScalerCrop, ControlInfo(Rectangle{}, Rectangle(65535, 65535, 65535, 65535), Rectangle{}) },
 	{ &controls::FrameDurationLimits, ControlInfo(INT64_C(33333), INT64_C(120000)) },
@@ -688,9 +691,17 @@  static const std::map<int32_t, RPiController::AfAlgorithm::AfPause> AfPauseTable
 	{ controls::AfPauseResume, RPiController::AfAlgorithm::AfPauseResume },
 };
 
+static const std::map<int32_t, std::string> HdrModeTable = {
+	{ controls::HdrModeOff, "Off" },
+	{ controls::HdrModeMultiExposure, "MultiExposure" },
+	{ controls::HdrModeSingleExposure, "SingleExposure" },
+};
+
 void IpaBase::applyControls(const ControlList &controls)
 {
+	using RPiController::AgcAlgorithm;
 	using RPiController::AfAlgorithm;
+	using RPiController::HdrAlgorithm;
 
 	/* Clear the return metadata buffer. */
 	libcameraMetadata_.clear();
@@ -1162,6 +1173,34 @@  void IpaBase::applyControls(const ControlList &controls)
 			break;
 		}
 
+		case controls::HDR_MODE: {
+			HdrAlgorithm *hdr = dynamic_cast<HdrAlgorithm *>(controller_.getAlgorithm("hdr"));
+			if (!hdr) {
+				LOG(IPARPI, Warning) << "No HDR algorithm available";
+				break;
+			}
+
+			auto mode = HdrModeTable.find(ctrl.second.get<int32_t>());
+			if (mode == HdrModeTable.end()) {
+				LOG(IPARPI, Warning) << "Unrecognised HDR mode";
+				break;
+			}
+
+			AgcAlgorithm *agc = dynamic_cast<AgcAlgorithm *>(controller_.getAlgorithm("agc"));
+			if (!agc) {
+				LOG(IPARPI, Warning) << "HDR requires an AGC algorithm";
+				break;
+			}
+
+			if (hdr->setMode(mode->second) == 0)
+				agc->setActiveChannels(hdr->getChannels());
+			else
+				LOG(IPARPI, Warning)
+					<< "HDR mode " << mode->second << " not supported";
+
+			break;
+		}
+
 		default:
 			LOG(IPARPI, Warning)
 				<< "Ctrl " << controls::controls.at(ctrl.first)->name()
@@ -1309,6 +1348,16 @@  void IpaBase::reportMetadata(unsigned int ipaContext)
 		libcameraMetadata_.set(controls::AfPauseState, p);
 	}
 
+	const HdrStatus *hdrStatus = rpiMetadata.getLocked<HdrStatus>("hdr.status");
+	if (hdrStatus) {
+		if (hdrStatus->channel == "short")
+			libcameraMetadata_.set(controls::HdrChannel, controls::HdrChannelShort);
+		else if (hdrStatus->channel == "long")
+			libcameraMetadata_.set(controls::HdrChannel, controls::HdrChannelLong);
+		else
+			libcameraMetadata_.set(controls::HdrChannel, controls::HdrChannelNone);
+	}
+
 	metadataReady.emit(libcameraMetadata_);
 }