pipeline: ipa: raspberrypi: Add HBLANK control to DelayedControls

Update CamHelper::getDelays() to return the sensor HBLANK delay. The
HBLANK delay is set to the same value as VBLANK delay for all sensors in
the Raspberry Pi IPA.

Return the HBLANK gain delay from the IPA to the pipeline handler, and
initialise DelayedControls to handle V4L2_CID_HBLANK with this delay
value.

As a drive-by, check that the V4L2_CID_HBLANK control is available when
calling IPARPi::configure().

Signed-off-by: Naushir Patuck <naush@raspberrypi.com>
Tested-by: Dave Stevenson <dave.stevenson@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 2022-10-06 14:17:39 +01:00 committed by Laurent Pinchart
parent f694da76be
commit aa2fe6a86f
11 changed files with 28 additions and 16 deletions

View file

@ -23,6 +23,7 @@ struct SensorConfig {
uint32 gainDelay; uint32 gainDelay;
uint32 exposureDelay; uint32 exposureDelay;
uint32 vblankDelay; uint32 vblankDelay;
uint32 hblankDelay;
uint32 sensorMetadata; uint32 sensorMetadata;
}; };

View file

@ -107,7 +107,7 @@ void CamHelper::setCameraMode(const CameraMode &mode)
} }
void CamHelper::getDelays(int &exposureDelay, int &gainDelay, void CamHelper::getDelays(int &exposureDelay, int &gainDelay,
int &vblankDelay) const int &vblankDelay, int &hblankDelay) const
{ {
/* /*
* These values are correct for many sensors. Other sensors will * These values are correct for many sensors. Other sensors will
@ -116,6 +116,7 @@ void CamHelper::getDelays(int &exposureDelay, int &gainDelay,
exposureDelay = 2; exposureDelay = 2;
gainDelay = 1; gainDelay = 1;
vblankDelay = 2; vblankDelay = 2;
hblankDelay = 2;
} }
bool CamHelper::sensorEmbeddedDataPresent() const bool CamHelper::sensorEmbeddedDataPresent() const

View file

@ -88,7 +88,7 @@ public:
virtual uint32_t gainCode(double gain) const = 0; virtual uint32_t gainCode(double gain) const = 0;
virtual double gain(uint32_t gainCode) const = 0; virtual double gain(uint32_t gainCode) const = 0;
virtual void getDelays(int &exposureDelay, int &gainDelay, virtual void getDelays(int &exposureDelay, int &gainDelay,
int &vblankDelay) const; int &vblankDelay, int &hblankDelay) const;
virtual bool sensorEmbeddedDataPresent() const; virtual bool sensorEmbeddedDataPresent() const;
virtual double getModeSensitivity(const CameraMode &mode) const; virtual double getModeSensitivity(const CameraMode &mode) const;
virtual unsigned int hideFramesStartup() const; virtual unsigned int hideFramesStartup() const;

View file

@ -18,7 +18,7 @@ public:
uint32_t gainCode(double gain) const override; uint32_t gainCode(double gain) const override;
double gain(uint32_t gainCode) const override; double gain(uint32_t gainCode) const override;
void getDelays(int &exposureDelay, int &gainDelay, void getDelays(int &exposureDelay, int &gainDelay,
int &vblankDelay) const override; int &vblankDelay, int &hblankDelay) const override;
unsigned int hideFramesModeSwitch() const override; unsigned int hideFramesModeSwitch() const override;
private: private:
@ -46,11 +46,12 @@ double CamHelperImx290::gain(uint32_t gainCode) const
} }
void CamHelperImx290::getDelays(int &exposureDelay, int &gainDelay, void CamHelperImx290::getDelays(int &exposureDelay, int &gainDelay,
int &vblankDelay) const int &vblankDelay, int &hblankDelay) const
{ {
exposureDelay = 2; exposureDelay = 2;
gainDelay = 2; gainDelay = 2;
vblankDelay = 2; vblankDelay = 2;
hblankDelay = 2;
} }
unsigned int CamHelperImx290::hideFramesModeSwitch() const unsigned int CamHelperImx290::hideFramesModeSwitch() const

View file

@ -23,7 +23,8 @@ public:
double gain(uint32_t gainCode) const override; double gain(uint32_t gainCode) const override;
uint32_t exposureLines(const Duration exposure, const Duration lineLength) const override; uint32_t exposureLines(const Duration exposure, const Duration lineLength) const override;
Duration exposure(uint32_t exposureLines, const Duration lineLength) const override; Duration exposure(uint32_t exposureLines, const Duration lineLength) const override;
void getDelays(int &exposureDelay, int &gainDelay, int &vblankDelay) const override; void getDelays(int &exposureDelay, int &gainDelay,
int &vblankDelay, int &hblankDelay) const override;
private: private:
static constexpr uint32_t minExposureLines = 1; static constexpr uint32_t minExposureLines = 1;
@ -66,11 +67,12 @@ Duration CamHelperImx296::exposure(uint32_t exposureLines,
} }
void CamHelperImx296::getDelays(int &exposureDelay, int &gainDelay, void CamHelperImx296::getDelays(int &exposureDelay, int &gainDelay,
int &vblankDelay) const int &vblankDelay, int &hblankDelay) const
{ {
exposureDelay = 2; exposureDelay = 2;
gainDelay = 2; gainDelay = 2;
vblankDelay = 2; vblankDelay = 2;
hblankDelay = 2;
} }
static CamHelper *create() static CamHelper *create()

View file

@ -49,7 +49,7 @@ public:
uint32_t getVBlanking(Duration &exposure, Duration minFrameDuration, uint32_t getVBlanking(Duration &exposure, Duration minFrameDuration,
Duration maxFrameDuration) const override; Duration maxFrameDuration) const override;
void getDelays(int &exposureDelay, int &gainDelay, void getDelays(int &exposureDelay, int &gainDelay,
int &vblankDelay) const override; int &vblankDelay, int &hblankDelay) const override;
bool sensorEmbeddedDataPresent() const override; bool sensorEmbeddedDataPresent() const override;
private: private:
@ -153,11 +153,12 @@ uint32_t CamHelperImx477::getVBlanking(Duration &exposure,
} }
void CamHelperImx477::getDelays(int &exposureDelay, int &gainDelay, void CamHelperImx477::getDelays(int &exposureDelay, int &gainDelay,
int &vblankDelay) const int &vblankDelay, int &hblankDelay) const
{ {
exposureDelay = 2; exposureDelay = 2;
gainDelay = 2; gainDelay = 2;
vblankDelay = 3; vblankDelay = 3;
hblankDelay = 3;
} }
bool CamHelperImx477::sensorEmbeddedDataPresent() const bool CamHelperImx477::sensorEmbeddedDataPresent() const

View file

@ -49,7 +49,7 @@ public:
uint32_t getVBlanking(Duration &exposure, Duration minFrameDuration, uint32_t getVBlanking(Duration &exposure, Duration minFrameDuration,
Duration maxFrameDuration) const override; Duration maxFrameDuration) const override;
void getDelays(int &exposureDelay, int &gainDelay, void getDelays(int &exposureDelay, int &gainDelay,
int &vblankDelay) const override; int &vblankDelay, int &hblankDelay) const override;
bool sensorEmbeddedDataPresent() const override; bool sensorEmbeddedDataPresent() const override;
private: private:
@ -153,11 +153,12 @@ uint32_t CamHelperImx519::getVBlanking(Duration &exposure,
} }
void CamHelperImx519::getDelays(int &exposureDelay, int &gainDelay, void CamHelperImx519::getDelays(int &exposureDelay, int &gainDelay,
int &vblankDelay) const int &vblankDelay, int &hblankDelay) const
{ {
exposureDelay = 2; exposureDelay = 2;
gainDelay = 2; gainDelay = 2;
vblankDelay = 3; vblankDelay = 3;
hblankDelay = 3;
} }
bool CamHelperImx519::sensorEmbeddedDataPresent() const bool CamHelperImx519::sensorEmbeddedDataPresent() const

View file

@ -18,7 +18,7 @@ public:
uint32_t gainCode(double gain) const override; uint32_t gainCode(double gain) const override;
double gain(uint32_t gainCode) const override; double gain(uint32_t gainCode) const override;
void getDelays(int &exposureDelay, int &gainDelay, void getDelays(int &exposureDelay, int &gainDelay,
int &vblankDelay) const override; int &vblankDelay, int &hblankDelay) const override;
unsigned int hideFramesStartup() const override; unsigned int hideFramesStartup() const override;
unsigned int hideFramesModeSwitch() const override; unsigned int hideFramesModeSwitch() const override;
unsigned int mistrustFramesStartup() const override; unsigned int mistrustFramesStartup() const override;
@ -53,7 +53,7 @@ double CamHelperOv5647::gain(uint32_t gainCode) const
} }
void CamHelperOv5647::getDelays(int &exposureDelay, int &gainDelay, void CamHelperOv5647::getDelays(int &exposureDelay, int &gainDelay,
int &vblankDelay) const int &vblankDelay, int &hblankDelay) const
{ {
/* /*
* We run this sensor in a mode where the gain delay is bumped up to * We run this sensor in a mode where the gain delay is bumped up to
@ -62,6 +62,7 @@ void CamHelperOv5647::getDelays(int &exposureDelay, int &gainDelay,
exposureDelay = 2; exposureDelay = 2;
gainDelay = 2; gainDelay = 2;
vblankDelay = 2; vblankDelay = 2;
hblankDelay = 2;
} }
unsigned int CamHelperOv5647::hideFramesStartup() const unsigned int CamHelperOv5647::hideFramesStartup() const

View file

@ -18,7 +18,7 @@ public:
uint32_t gainCode(double gain) const override; uint32_t gainCode(double gain) const override;
double gain(uint32_t gainCode) const override; double gain(uint32_t gainCode) const override;
void getDelays(int &exposureDelay, int &gainDelay, void getDelays(int &exposureDelay, int &gainDelay,
int &vblankDelay) const override; int &vblankDelay, int &hblankDelay) const override;
private: private:
/* /*
@ -49,12 +49,13 @@ double CamHelperOv9281::gain(uint32_t gainCode) const
} }
void CamHelperOv9281::getDelays(int &exposureDelay, int &gainDelay, void CamHelperOv9281::getDelays(int &exposureDelay, int &gainDelay,
int &vblankDelay) const int &vblankDelay, int &hblankDelay) const
{ {
/* The driver appears to behave as follows: */ /* The driver appears to behave as follows: */
exposureDelay = 2; exposureDelay = 2;
gainDelay = 2; gainDelay = 2;
vblankDelay = 2; vblankDelay = 2;
hblankDelay = 2;
} }
static CamHelper *create() static CamHelper *create()

View file

@ -219,13 +219,14 @@ int IPARPi::init(const IPASettings &settings, IPAInitResult *result)
* Pass out the sensor config to the pipeline handler in order * Pass out the sensor config to the pipeline handler in order
* to setup the staggered writer class. * to setup the staggered writer class.
*/ */
int gainDelay, exposureDelay, vblankDelay, sensorMetadata; int gainDelay, exposureDelay, vblankDelay, hblankDelay, sensorMetadata;
helper_->getDelays(exposureDelay, gainDelay, vblankDelay); helper_->getDelays(exposureDelay, gainDelay, vblankDelay, hblankDelay);
sensorMetadata = helper_->sensorEmbeddedDataPresent(); sensorMetadata = helper_->sensorEmbeddedDataPresent();
result->sensorConfig.gainDelay = gainDelay; result->sensorConfig.gainDelay = gainDelay;
result->sensorConfig.exposureDelay = exposureDelay; result->sensorConfig.exposureDelay = exposureDelay;
result->sensorConfig.vblankDelay = vblankDelay; result->sensorConfig.vblankDelay = vblankDelay;
result->sensorConfig.hblankDelay = hblankDelay;
result->sensorConfig.sensorMetadata = sensorMetadata; result->sensorConfig.sensorMetadata = sensorMetadata;
/* Load the tuning file for this sensor. */ /* Load the tuning file for this sensor. */
@ -606,6 +607,7 @@ bool IPARPi::validateSensorControls()
V4L2_CID_ANALOGUE_GAIN, V4L2_CID_ANALOGUE_GAIN,
V4L2_CID_EXPOSURE, V4L2_CID_EXPOSURE,
V4L2_CID_VBLANK, V4L2_CID_VBLANK,
V4L2_CID_HBLANK,
}; };
for (auto c : ctrls) { for (auto c : ctrls) {

View file

@ -1297,6 +1297,7 @@ int PipelineHandlerRPi::registerCamera(MediaDevice *unicam, MediaDevice *isp, Me
std::unordered_map<uint32_t, DelayedControls::ControlParams> params = { std::unordered_map<uint32_t, DelayedControls::ControlParams> params = {
{ V4L2_CID_ANALOGUE_GAIN, { result.sensorConfig.gainDelay, false } }, { V4L2_CID_ANALOGUE_GAIN, { result.sensorConfig.gainDelay, false } },
{ V4L2_CID_EXPOSURE, { result.sensorConfig.exposureDelay, false } }, { V4L2_CID_EXPOSURE, { result.sensorConfig.exposureDelay, false } },
{ V4L2_CID_HBLANK, { result.sensorConfig.hblankDelay, false } },
{ V4L2_CID_VBLANK, { result.sensorConfig.vblankDelay, true } } { V4L2_CID_VBLANK, { result.sensorConfig.vblankDelay, true } }
}; };
data->delayedCtrls_ = std::make_unique<DelayedControls>(data->sensor_->device(), params); data->delayedCtrls_ = std::make_unique<DelayedControls>(data->sensor_->device(), params);