[PATCH 5/6] ipa: rpi: Handle the new CNN controls in the IPA

David Plowman david.plowman at raspberrypi.com
Fri Dec 13 11:32:53 CET 2024


Hi Naush

Thanks for the patch!

On Fri, 13 Dec 2024 at 09:46, Naushir Patuck <naush at raspberrypi.com> wrote:
>
> Add code to handle the new CNN vendor controls in the Raspberry Pi IPA.
>
> The value of CnnInputTensorInfo is cached as it is the only stateful
> input control.

Just wanted to check that you didn't mean CnnEnableInputTensor, rather
than CnnInputTensorInfo?

Other than that, it all looked fine to me, so apart from the above question:

Reviewed-by: David Plowman <david.plowman at raspberrypi.com>

Thanks
David

>
> All other controls are output controls, and the values are copied into
> directly from the rpiMetadata object if present. The camera helpers
> populate the rpiMetadata object if the sensor supports on-board CNN
> processing, such as the IMX500.
>
> Signed-off-by: Naushir Patuck <naush at raspberrypi.com>
> ---
>  src/ipa/rpi/common/ipa_base.cpp | 52 ++++++++++++++++++++++++++++++++-
>  src/ipa/rpi/common/ipa_base.h   |  2 ++
>  2 files changed, 53 insertions(+), 1 deletion(-)
>
> diff --git a/src/ipa/rpi/common/ipa_base.cpp b/src/ipa/rpi/common/ipa_base.cpp
> index 5fce17e67bd6..b3656cbc730b 100644
> --- a/src/ipa/rpi/common/ipa_base.cpp
> +++ b/src/ipa/rpi/common/ipa_base.cpp
> @@ -74,6 +74,7 @@ const ControlInfoMap::Map ipaControls{
>         { &controls::FrameDurationLimits, ControlInfo(INT64_C(33333), INT64_C(120000)) },
>         { &controls::draft::NoiseReductionMode, ControlInfo(controls::draft::NoiseReductionModeValues) },
>         { &controls::rpi::StatsOutputEnable, ControlInfo(false, true, false) },
> +       { &controls::rpi::CnnEnableInputTensor, ControlInfo(false, true, false) },
>  };
>
>  /* IPA controls handled conditionally, if the sensor is not mono */
> @@ -112,7 +113,7 @@ namespace ipa::RPi {
>  IpaBase::IpaBase()
>         : controller_(), frameLengths_(FrameLengthsQueueSize, 0s), statsMetadataOutput_(false),
>           stitchSwapBuffers_(false), frameCount_(0), mistrustCount_(0), lastRunTimestamp_(0),
> -         firstStart_(true), flickerState_({ 0, 0s })
> +         firstStart_(true), flickerState_({ 0, 0s }), cnnEnableInputTensor_(false)
>  {
>  }
>
> @@ -1263,6 +1264,10 @@ void IpaBase::applyControls(const ControlList &controls)
>                         statsMetadataOutput_ = ctrl.second.get<bool>();
>                         break;
>
> +               case controls::rpi::CNN_ENABLE_INPUT_TENSOR:
> +                       cnnEnableInputTensor_ = ctrl.second.get<bool>();
> +                       break;
> +
>                 default:
>                         LOG(IPARPI, Warning)
>                                 << "Ctrl " << controls::controls.at(ctrl.first)->name()
> @@ -1439,6 +1444,51 @@ void IpaBase::reportMetadata(unsigned int ipaContext)
>                         libcameraMetadata_.set(controls::HdrChannel, controls::HdrChannelNone);
>         }
>
> +       const std::shared_ptr<uint8_t[]> *inputTensor =
> +               rpiMetadata.getLocked<std::shared_ptr<uint8_t[]>>("cnn.input_tensor");
> +       if (cnnEnableInputTensor_ && inputTensor) {
> +               unsigned int size = *rpiMetadata.getLocked<unsigned int>("cnn.input_tensor_size");
> +               Span<const uint8_t> tensor{ inputTensor->get(), size };
> +               libcameraMetadata_.set(controls::rpi::CnnInputTensor, tensor);
> +               /* No need to keep these big buffers any more. */
> +               rpiMetadata.eraseLocked("cnn.input_tensor");
> +       }
> +
> +       const RPiController::CnnInputTensorInfo *inputTensorInfo =
> +               rpiMetadata.getLocked<RPiController::CnnInputTensorInfo>("cnn.input_tensor_info");
> +       if (inputTensorInfo) {
> +               Span<const uint8_t> tensorInfo{ reinterpret_cast<const uint8_t *>(inputTensorInfo),
> +                                               sizeof(*inputTensorInfo) };
> +               libcameraMetadata_.set(controls::rpi::CnnInputTensorInfo, tensorInfo);
> +       }
> +
> +       const std::shared_ptr<float[]> *outputTensor =
> +               rpiMetadata.getLocked<std::shared_ptr<float[]>>("cnn.output_tensor");
> +       if (outputTensor) {
> +               unsigned int size = *rpiMetadata.getLocked<unsigned int>("cnn.output_tensor_size");
> +               Span<const float> tensor{ reinterpret_cast<const float *>(outputTensor->get()),
> +                                         size };
> +               libcameraMetadata_.set(controls::rpi::CnnOutputTensor, tensor);
> +               /* No need to keep these big buffers any more. */
> +               rpiMetadata.eraseLocked("cnn.output_tensor");
> +       }
> +
> +       const RPiController::CnnOutputTensorInfo *outputTensorInfo =
> +               rpiMetadata.getLocked<RPiController::CnnOutputTensorInfo>("cnn.output_tensor_info");
> +       if (outputTensorInfo) {
> +               Span<const uint8_t> tensorInfo{ reinterpret_cast<const uint8_t *>(outputTensorInfo),
> +                                               sizeof(*outputTensorInfo) };
> +               libcameraMetadata_.set(controls::rpi::CnnOutputTensorInfo, tensorInfo);
> +       }
> +
> +       const RPiController::CnnKpiInfo *kpiInfo =
> +               rpiMetadata.getLocked<RPiController::CnnKpiInfo>("cnn.kpi_info");
> +       if (kpiInfo) {
> +               libcameraMetadata_.set(controls::rpi::CnnKpiInfo,
> +                                      { static_cast<int32_t>(kpiInfo->dnnRuntime),
> +                                        static_cast<int32_t>(kpiInfo->dspRuntime) });
> +       }
> +
>         metadataReady.emit(libcameraMetadata_);
>  }
>
> diff --git a/src/ipa/rpi/common/ipa_base.h b/src/ipa/rpi/common/ipa_base.h
> index 1a811beb31f2..a55ce7ca9fa3 100644
> --- a/src/ipa/rpi/common/ipa_base.h
> +++ b/src/ipa/rpi/common/ipa_base.h
> @@ -136,6 +136,8 @@ private:
>                 int32_t mode;
>                 utils::Duration manualPeriod;
>         } flickerState_;
> +
> +       bool cnnEnableInputTensor_;
>  };
>
>  } /* namespace ipa::RPi */
> --
> 2.43.0
>


More information about the libcamera-devel mailing list