diff options
author | Naushir Patuck <naush@raspberrypi.com> | 2023-05-03 13:20:27 +0100 |
---|---|---|
committer | Laurent Pinchart <laurent.pinchart@ideasonboard.com> | 2023-05-04 20:47:40 +0300 |
commit | 726e9274ea95fa46352556d340c5793a8da51fcd (patch) | |
tree | 80f6adcdbf744f9317e09eff3e80c602b384a753 /src/ipa/raspberrypi/cam_helper_imx477.cpp | |
parent | 46aefed208fef4bc8d6f6e8882b92b9af710a60b (diff) |
pipeline: ipa: raspberrypi: Refactor and move the Raspberry Pi code
Split the Raspberry Pi pipeline handler and IPA source code into common
and VC4/BCM2835 specific file structures.
For the pipeline handler, the common code files now live in
src/libcamera/pipeline/rpi/common/
and the VC4-specific files in src/libcamera/pipeline/rpi/vc4/.
For the IPA, the common code files now live in
src/ipa/rpi/{cam_helper,controller}/
and the vc4 specific files in src/ipa/rpi/vc4/. With this change, the
camera tuning files are now installed under share/libcamera/ipa/rpi/vc4/.
To build the pipeline and IPA, the meson configuration options have now
changed from "raspberrypi" to "rpi/vc4":
meson setup build -Dipas=rpi/vc4 -Dpipelines=rpi/vc4
Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com>
Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Diffstat (limited to 'src/ipa/raspberrypi/cam_helper_imx477.cpp')
-rw-r--r-- | src/ipa/raspberrypi/cam_helper_imx477.cpp | 197 |
1 files changed, 0 insertions, 197 deletions
diff --git a/src/ipa/raspberrypi/cam_helper_imx477.cpp b/src/ipa/raspberrypi/cam_helper_imx477.cpp deleted file mode 100644 index bc769ca7..00000000 --- a/src/ipa/raspberrypi/cam_helper_imx477.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* SPDX-License-Identifier: BSD-2-Clause */ -/* - * Copyright (C) 2020, Raspberry Pi Ltd - * - * cam_helper_imx477.cpp - camera helper for imx477 sensor - */ - -#include <algorithm> -#include <assert.h> -#include <cmath> -#include <stddef.h> -#include <stdio.h> -#include <stdlib.h> - -#include <libcamera/base/log.h> - -#include "cam_helper.h" -#include "md_parser.h" - -using namespace RPiController; -using namespace libcamera; -using libcamera::utils::Duration; - -namespace libcamera { -LOG_DECLARE_CATEGORY(IPARPI) -} - -/* - * We care about two gain registers and a pair of exposure registers. Their - * I2C addresses from the Sony IMX477 datasheet: - */ -constexpr uint32_t expHiReg = 0x0202; -constexpr uint32_t expLoReg = 0x0203; -constexpr uint32_t gainHiReg = 0x0204; -constexpr uint32_t gainLoReg = 0x0205; -constexpr uint32_t frameLengthHiReg = 0x0340; -constexpr uint32_t frameLengthLoReg = 0x0341; -constexpr uint32_t lineLengthHiReg = 0x0342; -constexpr uint32_t lineLengthLoReg = 0x0343; -constexpr uint32_t temperatureReg = 0x013a; -constexpr std::initializer_list<uint32_t> registerList = - { expHiReg, expLoReg, gainHiReg, gainLoReg, frameLengthHiReg, frameLengthLoReg, - lineLengthHiReg, lineLengthLoReg, temperatureReg }; - -class CamHelperImx477 : public CamHelper -{ -public: - CamHelperImx477(); - uint32_t gainCode(double gain) const override; - double gain(uint32_t gainCode) const override; - void prepare(libcamera::Span<const uint8_t> buffer, Metadata &metadata) override; - std::pair<uint32_t, uint32_t> getBlanking(Duration &exposure, Duration minFrameDuration, - Duration maxFrameDuration) const override; - void getDelays(int &exposureDelay, int &gainDelay, - int &vblankDelay, int &hblankDelay) const override; - bool sensorEmbeddedDataPresent() const override; - -private: - /* - * Smallest difference between the frame length and integration time, - * in units of lines. - */ - static constexpr int frameIntegrationDiff = 22; - /* Maximum frame length allowable for long exposure calculations. */ - static constexpr int frameLengthMax = 0xffdc; - /* Largest long exposure scale factor given as a left shift on the frame length. */ - static constexpr int longExposureShiftMax = 7; - - void populateMetadata(const MdParser::RegisterMap ®isters, - Metadata &metadata) const override; -}; - -CamHelperImx477::CamHelperImx477() - : CamHelper(std::make_unique<MdParserSmia>(registerList), frameIntegrationDiff) -{ -} - -uint32_t CamHelperImx477::gainCode(double gain) const -{ - return static_cast<uint32_t>(1024 - 1024 / gain); -} - -double CamHelperImx477::gain(uint32_t gainCode) const -{ - return 1024.0 / (1024 - gainCode); -} - -void CamHelperImx477::prepare(libcamera::Span<const uint8_t> buffer, Metadata &metadata) -{ - MdParser::RegisterMap registers; - DeviceStatus deviceStatus; - - if (metadata.get("device.status", deviceStatus)) { - LOG(IPARPI, Error) << "DeviceStatus not found from DelayedControls"; - return; - } - - parseEmbeddedData(buffer, metadata); - - /* - * The DeviceStatus struct is first populated with values obtained from - * DelayedControls. If this reports frame length is > frameLengthMax, - * it means we are using a long exposure mode. Since the long exposure - * scale factor is not returned back through embedded data, we must rely - * on the existing exposure lines and frame length values returned by - * DelayedControls. - * - * Otherwise, all values are updated with what is reported in the - * embedded data. - */ - if (deviceStatus.frameLength > frameLengthMax) { - DeviceStatus parsedDeviceStatus; - - metadata.get("device.status", parsedDeviceStatus); - parsedDeviceStatus.shutterSpeed = deviceStatus.shutterSpeed; - parsedDeviceStatus.frameLength = deviceStatus.frameLength; - metadata.set("device.status", parsedDeviceStatus); - - LOG(IPARPI, Debug) << "Metadata updated for long exposure: " - << parsedDeviceStatus; - } -} - -std::pair<uint32_t, uint32_t> CamHelperImx477::getBlanking(Duration &exposure, - Duration minFrameDuration, - Duration maxFrameDuration) const -{ - uint32_t frameLength, exposureLines; - unsigned int shift = 0; - - auto [vblank, hblank] = CamHelper::getBlanking(exposure, minFrameDuration, - maxFrameDuration); - - frameLength = mode_.height + vblank; - Duration lineLength = hblankToLineLength(hblank); - - /* - * Check if the frame length calculated needs to be setup for long - * exposure mode. This will require us to use a long exposure scale - * factor provided by a shift operation in the sensor. - */ - while (frameLength > frameLengthMax) { - if (++shift > longExposureShiftMax) { - shift = longExposureShiftMax; - frameLength = frameLengthMax; - break; - } - frameLength >>= 1; - } - - if (shift) { - /* Account for any rounding in the scaled frame length value. */ - frameLength <<= shift; - exposureLines = CamHelperImx477::exposureLines(exposure, lineLength); - exposureLines = std::min(exposureLines, frameLength - frameIntegrationDiff); - exposure = CamHelperImx477::exposure(exposureLines, lineLength); - } - - return { frameLength - mode_.height, hblank }; -} - -void CamHelperImx477::getDelays(int &exposureDelay, int &gainDelay, - int &vblankDelay, int &hblankDelay) const -{ - exposureDelay = 2; - gainDelay = 2; - vblankDelay = 3; - hblankDelay = 3; -} - -bool CamHelperImx477::sensorEmbeddedDataPresent() const -{ - return true; -} - -void CamHelperImx477::populateMetadata(const MdParser::RegisterMap ®isters, - Metadata &metadata) const -{ - DeviceStatus deviceStatus; - - deviceStatus.lineLength = lineLengthPckToDuration(registers.at(lineLengthHiReg) * 256 + - registers.at(lineLengthLoReg)); - deviceStatus.shutterSpeed = exposure(registers.at(expHiReg) * 256 + registers.at(expLoReg), - deviceStatus.lineLength); - deviceStatus.analogueGain = gain(registers.at(gainHiReg) * 256 + registers.at(gainLoReg)); - deviceStatus.frameLength = registers.at(frameLengthHiReg) * 256 + registers.at(frameLengthLoReg); - deviceStatus.sensorTemperature = std::clamp<int8_t>(registers.at(temperatureReg), -20, 80); - - metadata.set("device.status", deviceStatus); -} - -static CamHelper *create() -{ - return new CamHelperImx477(); -} - -static RegisterCamHelper reg("imx477", &create); |