Skip to content

Commit

Permalink
ipa: rpi: Handle the new CNN controls in the IPA
Browse files Browse the repository at this point in the history
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.

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 <[email protected]>
  • Loading branch information
naushir committed Sep 25, 2024
1 parent a401e82 commit dc7c297
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 1 deletion.
52 changes: 51 additions & 1 deletion src/ipa/rpi/common/ipa_base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,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 */
Expand Down Expand Up @@ -106,7 +107,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)
{
}

Expand Down Expand Up @@ -1249,6 +1250,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()
Expand Down Expand Up @@ -1425,6 +1430,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_);
}

Expand Down
2 changes: 2 additions & 0 deletions src/ipa/rpi/common/ipa_base.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,8 @@ class IpaBase : public IPARPiInterface
int32_t mode;
utils::Duration manualPeriod;
} flickerState_;

bool cnnEnableInputTensor_;
};

} /* namespace ipa::RPi */
Expand Down

0 comments on commit dc7c297

Please sign in to comment.