Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions src/ipa/rpi/controller/decompand_algorithm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (C) 2025, Raspberry Pi Ltd
*
* Decompand control algorithm interface
*/
#pragma once

#include "libipa/pwl.h"

#include "algorithm.h"

namespace RPiController {

class DecompandAlgorithm : public Algorithm
{
public:
DecompandAlgorithm(Controller *controller = NULL)
: Algorithm(controller)
{
}
/* A decompand algorithm must provide the following: */
virtual void initialValues(libcamera::ipa::Pwl &decompandCurve) = 0;
};

} /* namespace RPiController */
10 changes: 9 additions & 1 deletion src/ipa/rpi/controller/rpi/decompand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ LOG_DEFINE_CATEGORY(RPiDecompand)
#define NAME "rpi.decompand"

Decompand::Decompand(Controller *controller)
: Algorithm(controller)
: DecompandAlgorithm(controller)
{
}

Expand All @@ -39,6 +39,14 @@ void Decompand::switchMode([[maybe_unused]] CameraMode const &cameraMode,
mode_ = cameraMode;
}

void Decompand::initialValues(libcamera::ipa::Pwl &decompandCurve)
{
if (config_.bitdepth == 0 || mode_.bitdepth == config_.bitdepth) {
decompandCurve = config_.decompandCurve;
} else
decompandCurve = {};
}

void Decompand::prepare(Metadata *imageMetadata)
{
DecompandStatus decompandStatus;
Expand Down
6 changes: 3 additions & 3 deletions src/ipa/rpi/controller/rpi/decompand.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,25 @@

#include <libipa/pwl.h>

#include "../decompand_algorithm.h"
#include "../decompand_status.h"

#include "algorithm.h"

namespace RPiController {

struct DecompandConfig {
uint32_t bitdepth;
libcamera::ipa::Pwl decompandCurve;
};

class Decompand : public Algorithm
class Decompand : public DecompandAlgorithm
{
public:
Decompand(Controller *controller = NULL);
char const *name() const override;
int read(const libcamera::YamlObject &params) override;
void initialise() override;
void switchMode(CameraMode const &cameraMode, Metadata *metadata) override;
void initialValues(libcamera::ipa::Pwl &decompandCurve) override;
void prepare(Metadata *imageMetadata) override;

private:
Expand Down
32 changes: 24 additions & 8 deletions src/ipa/rpi/pisp/pisp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "controller/cac_status.h"
#include "controller/ccm_status.h"
#include "controller/contrast_status.h"
#include "controller/decompand_algorithm.h"
#include "controller/decompand_status.h"
#include "controller/denoise_algorithm.h"
#include "controller/denoise_status.h"
Expand Down Expand Up @@ -256,7 +257,7 @@ class IpaPiSP final : public IpaBase
void applyLensShading(const AlscStatus *alscStatus,
pisp_be_global_config &global);
void applyDPC(const DpcStatus *dpcStatus, pisp_be_global_config &global);
void applyDecompand(const DecompandStatus *decompandStatus);
void applyDecompand(const DecompandStatus *decompandStatus, pisp_fe_global_config &feGlobal);
void applySdn(const SdnStatus *sdnStatus, pisp_be_global_config &global);
void applyTdn(const TdnStatus *tdnStatus, const DeviceStatus *deviceStatus,
pisp_be_global_config &global);
Expand Down Expand Up @@ -335,6 +336,20 @@ int32_t IpaPiSP::platformStart([[maybe_unused]] const ControlList &controls,
/* Cause the stitch block to be reset correctly. */
lastStitchHdrStatus_ = HdrStatus();

/* Setup a default decompand curve on startup if needed. */
RPiController::DecompandAlgorithm *decompand = dynamic_cast<RPiController::DecompandAlgorithm *>(
controller_.getAlgorithm("decompand"));
if (decompand) {
std::scoped_lock<FrontEnd> l(*fe_);
pisp_fe_global_config feGlobal;
DecompandStatus decompandStatus;

fe_->GetGlobal(feGlobal);
decompand->initialValues(decompandStatus.decompandCurve);
applyDecompand(&decompandStatus, feGlobal);
fe_->SetGlobal(feGlobal);
}

return 0;
}

Expand Down Expand Up @@ -368,20 +383,24 @@ void IpaPiSP::platformPrepareIsp([[maybe_unused]] const PrepareParams &params,
{
/* All Frontend config goes first, we do not want to hold the FE lock for long! */
std::scoped_lock<FrontEnd> lf(*fe_);
pisp_fe_global_config feGlobal;

fe_->GetGlobal(feGlobal);

if (noiseStatus)
applyFocusStats(noiseStatus);

DecompandStatus *decompandStatus =
rpiMetadata.getLocked<DecompandStatus>("decompand.status");
if (decompandStatus)
applyDecompand(decompandStatus);
applyDecompand(decompandStatus, feGlobal);

BlackLevelStatus *blackLevelStatus =
rpiMetadata.getLocked<BlackLevelStatus>("black_level.status");
if (blackLevelStatus)
applyBlackLevel(blackLevelStatus, global);

fe_->SetGlobal(feGlobal);
}

CacStatus *cacStatus = rpiMetadata.getLocked<CacStatus>("cac.status");
Expand Down Expand Up @@ -728,18 +747,15 @@ void IpaPiSP::applyDPC(const DpcStatus *dpcStatus, pisp_be_global_config &global
be_->SetDpc(dpc);
}

void IpaPiSP::applyDecompand(const DecompandStatus *decompandStatus)
void IpaPiSP::applyDecompand(const DecompandStatus *decompandStatus, pisp_fe_global_config &feGlobal)
{
pisp_fe_global_config feGlobal;
pisp_fe_decompand_config decompand = {};

fe_->GetGlobal(feGlobal);

if (!generateDecompandLut(decompandStatus->decompandCurve, decompand.lut, PISP_FE_DECOMPAND_LUT_SIZE)) {
fe_->SetDecompand(decompand);
feGlobal.enables |= PISP_FE_ENABLE_DECOMPAND;
fe_->SetGlobal(feGlobal);
}
} else
feGlobal.enables &= ~PISP_FE_ENABLE_DECOMPAND;
}

void IpaPiSP::applySdn(const SdnStatus *sdnStatus, pisp_be_global_config &global)
Expand Down