summaryrefslogtreecommitdiff
path: root/src/ipa/raspberrypi/cam_helper_imx477.cpp
diff options
context:
space:
mode:
authorNaushir Patuck <naush@raspberrypi.com>2023-05-03 13:20:27 +0100
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2023-05-04 20:47:40 +0300
commit726e9274ea95fa46352556d340c5793a8da51fcd (patch)
tree80f6adcdbf744f9317e09eff3e80c602b384a753 /src/ipa/raspberrypi/cam_helper_imx477.cpp
parent46aefed208fef4bc8d6f6e8882b92b9af710a60b (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.cpp197
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 &registers,
- 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 &registers,
- 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);