ipa: raspberrypi: Generalise the SMIA metadata parser

Instead of having each CamHelper subclass the MdParserSmia, change the
implementation of MdParserSmia to be more generic. The MdParserSmia now gets
given a list of registers to search for and helper functions are used to compute
exposure lines and gain codes from these registers.

Update the imx219 and imx477 CamHelpers by using this new mechanism.

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
Naushir Patuck 2021-06-29 11:45:00 +01:00 committed by Laurent Pinchart
parent d3ea8e7885
commit 579f55b108
6 changed files with 149 additions and 240 deletions

View file

@ -23,21 +23,14 @@
using namespace RPiController;
/* Metadata parser implementation specific to Sony IMX219 sensors. */
class MdParserImx219 : public MdParserSmia
{
public:
MdParserImx219();
Status Parse(libcamera::Span<const uint8_t> buffer) override;
Status GetExposureLines(unsigned int &lines) override;
Status GetGainCode(unsigned int &gain_code) override;
private:
/* Offset of the register's value in the metadata block. */
int reg_offsets_[3];
/* Value of the register, once read from the metadata block. */
int reg_values_[3];
};
/*
* We care about one gain register and a pair of exposure registers. Their I2C
* addresses from the Sony IMX219 datasheet:
*/
constexpr uint32_t gainReg = 0x157;
constexpr uint32_t expHiReg = 0x15a;
constexpr uint32_t expLoReg = 0x15b;
constexpr std::initializer_list<uint32_t> registerList [[maybe_unused]] = { expHiReg, expLoReg, gainReg };
class CamHelperImx219 : public CamHelper
{
@ -54,11 +47,14 @@ private:
* in units of lines.
*/
static constexpr int frameIntegrationDiff = 4;
void PopulateMetadata(const MdParser::RegisterMap &registers,
Metadata &metadata) const override;
};
CamHelperImx219::CamHelperImx219()
#if ENABLE_EMBEDDED_DATA
: CamHelper(std::make_unique<MdParserImx219>(), frameIntegrationDiff)
: CamHelper(std::make_unique<MdParserSmia>(registerList), frameIntegrationDiff)
#else
: CamHelper({}, frameIntegrationDiff)
#endif
@ -90,88 +86,20 @@ bool CamHelperImx219::SensorEmbeddedDataPresent() const
return ENABLE_EMBEDDED_DATA;
}
void CamHelperImx219::PopulateMetadata(const MdParser::RegisterMap &registers,
Metadata &metadata) const
{
DeviceStatus deviceStatus;
deviceStatus.shutter_speed = Exposure(registers.at(expHiReg) * 256 + registers.at(expLoReg));
deviceStatus.analogue_gain = Gain(registers.at(gainReg));
metadata.Set("device.status", deviceStatus);
}
static CamHelper *Create()
{
return new CamHelperImx219();
}
static RegisterCamHelper reg("imx219", &Create);
/*
* We care about one gain register and a pair of exposure registers. Their I2C
* addresses from the Sony IMX219 datasheet:
*/
#define GAIN_REG 0x157
#define EXPHI_REG 0x15A
#define EXPLO_REG 0x15B
/*
* Index of each into the reg_offsets and reg_values arrays. Must be in
* register address order.
*/
#define GAIN_INDEX 0
#define EXPHI_INDEX 1
#define EXPLO_INDEX 2
MdParserImx219::MdParserImx219()
{
reg_offsets_[0] = reg_offsets_[1] = reg_offsets_[2] = -1;
}
MdParser::Status MdParserImx219::Parse(libcamera::Span<const uint8_t> buffer)
{
bool try_again = false;
if (reset_) {
/*
* Search again through the metadata for the gain and exposure
* registers.
*/
assert(bits_per_pixel_);
/* Need to be ordered */
uint32_t regs[3] = { GAIN_REG, EXPHI_REG, EXPLO_REG };
reg_offsets_[0] = reg_offsets_[1] = reg_offsets_[2] = -1;
int ret = static_cast<int>(findRegs(buffer,
regs, reg_offsets_, 3));
/*
* > 0 means "worked partially but parse again next time",
* < 0 means "hard error".
*/
if (ret > 0)
try_again = true;
else if (ret < 0)
return ERROR;
}
for (int i = 0; i < 3; i++) {
if (reg_offsets_[i] == -1)
continue;
reg_values_[i] = buffer[reg_offsets_[i]];
}
/* Re-parse next time if we were unhappy in some way. */
reset_ = try_again;
return OK;
}
MdParser::Status MdParserImx219::GetExposureLines(unsigned int &lines)
{
if (reg_offsets_[EXPHI_INDEX] == -1 || reg_offsets_[EXPLO_INDEX] == -1)
return NOTFOUND;
lines = reg_values_[EXPHI_INDEX] * 256 + reg_values_[EXPLO_INDEX];
return OK;
}
MdParser::Status MdParserImx219::GetGainCode(unsigned int &gain_code)
{
if (reg_offsets_[GAIN_INDEX] == -1)
return NOTFOUND;
gain_code = reg_values_[GAIN_INDEX];
return OK;
}