[libcamera-devel] [PATCH 2/2] libcamera: raspberrypi: Limit the maximum framerate to 30.0fps
Naushir Patuck
naush at raspberrypi.com
Mon May 11 12:01:50 CEST 2020
With the previous change to adapt framerate using VBLANK, the maximum
framerate was limited by the sensor mode. This may not be entirely
appropriate for what an application expects in the case where a mode
can produce > 30.0fps.
Provide a mechanism to limit the maximum framerate. This is currently
a const set to 30.0fps. In future, this value could be passed in via
a Request or stream configuration.
Signed-off-by: Naushir Patuck <naush at raspberrypi.com>
---
src/ipa/raspberrypi/cam_helper.hpp | 2 +-
src/ipa/raspberrypi/cam_helper_imx219.cpp | 18 ++++++++++++++----
src/ipa/raspberrypi/cam_helper_imx477.cpp | 18 ++++++++++++++----
src/ipa/raspberrypi/cam_helper_ov5647.cpp | 18 ++++++++++++++----
src/ipa/raspberrypi/raspberrypi.cpp | 8 +++++++-
5 files changed, 50 insertions(+), 14 deletions(-)
diff --git a/src/ipa/raspberrypi/cam_helper.hpp b/src/ipa/raspberrypi/cam_helper.hpp
index 37281c78..4f7a3897 100644
--- a/src/ipa/raspberrypi/cam_helper.hpp
+++ b/src/ipa/raspberrypi/cam_helper.hpp
@@ -74,7 +74,7 @@ public:
MdParser &Parser() const { return *parser_; }
uint32_t ExposureLines(double exposure_us) const;
double Exposure(uint32_t exposure_lines) const; // in us
- virtual uint32_t GetVBlanking(double exposure_us) const = 0;
+ virtual uint32_t GetVBlanking(double exposure_us, double maxFps) const = 0;
virtual uint32_t GainCode(double gain) const = 0;
virtual double Gain(uint32_t gain_code) const = 0;
virtual void GetDelays(int &exposure_delay, int &gain_delay) const;
diff --git a/src/ipa/raspberrypi/cam_helper_imx219.cpp b/src/ipa/raspberrypi/cam_helper_imx219.cpp
index d34a1f1f..51a18aca 100644
--- a/src/ipa/raspberrypi/cam_helper_imx219.cpp
+++ b/src/ipa/raspberrypi/cam_helper_imx219.cpp
@@ -45,7 +45,7 @@ class CamHelperImx219 : public CamHelper
{
public:
CamHelperImx219();
- uint32_t GetVBlanking(double exposure) const override;
+ uint32_t GetVBlanking(double exposure, double maxFps) const override;
uint32_t GainCode(double gain) const override;
double Gain(uint32_t gain_code) const override;
unsigned int MistrustFramesModeSwitch() const override;
@@ -55,6 +55,8 @@ public:
private:
/* Smallest difference between the frame length and integration time. */
static constexpr int frameIntegrationDiff = 4;
+ /* Largest possible frame length. */
+ static constexpr int maxFrameLength = 0xffff;
};
CamHelperImx219::CamHelperImx219()
@@ -66,12 +68,20 @@ CamHelperImx219::CamHelperImx219()
{
}
-uint32_t CamHelperImx219::GetVBlanking(double exposure) const
+uint32_t CamHelperImx219::GetVBlanking(double exposure, double maxFps) const
{
+ uint32_t frameLengthMin, vblank;
uint32_t exposureLines = ExposureLines(exposure);
- return std::max<uint32_t>(mode_.height, exposureLines) -
- mode_.height + frameIntegrationDiff;
+ vblank = std::max<uint32_t>(mode_.height, exposureLines) -
+ mode_.height + frameIntegrationDiff;
+
+ /* Limit the vblank to the maximum framerate requested. */
+ frameLengthMin = std::min<uint32_t>(1e9 / (mode_.line_length * maxFps),
+ maxFrameLength);
+ vblank = std::max(vblank, frameLengthMin - mode_.height);
+
+ return vblank;
}
uint32_t CamHelperImx219::GainCode(double gain) const
diff --git a/src/ipa/raspberrypi/cam_helper_imx477.cpp b/src/ipa/raspberrypi/cam_helper_imx477.cpp
index 242d9689..ff815f9c 100644
--- a/src/ipa/raspberrypi/cam_helper_imx477.cpp
+++ b/src/ipa/raspberrypi/cam_helper_imx477.cpp
@@ -35,7 +35,7 @@ class CamHelperImx477 : public CamHelper
{
public:
CamHelperImx477();
- uint32_t GetVBlanking(double exposure) const override;
+ uint32_t GetVBlanking(double exposure, double maxFps) const override;
uint32_t GainCode(double gain) const override;
double Gain(uint32_t gain_code) const override;
bool SensorEmbeddedDataPresent() const override;
@@ -44,6 +44,8 @@ public:
private:
/* Smallest difference between the frame length and integration time. */
static constexpr int frameIntegrationDiff = 22;
+ /* Largest possible frame length. */
+ static constexpr int maxFrameLength = 0xffdc;
};
CamHelperImx477::CamHelperImx477()
@@ -51,12 +53,20 @@ CamHelperImx477::CamHelperImx477()
{
}
-uint32_t CamHelperImx477::GetVBlanking(double exposure) const
+uint32_t CamHelperImx477::GetVBlanking(double exposure, double maxFps) const
{
+ uint32_t frameLengthMin, vblank;
uint32_t exposureLines = ExposureLines(exposure);
- return std::max<uint32_t>(mode_.height, exposureLines) -
- mode_.height + frameIntegrationDiff;
+ vblank = std::max<uint32_t>(mode_.height, exposureLines) -
+ mode_.height + frameIntegrationDiff;
+
+ /* Limit the vblank to the maximum framerate requested. */
+ frameLengthMin = std::min<uint32_t>(1e9 / (mode_.line_length * maxFps),
+ maxFrameLength);
+ vblank = std::max(vblank, frameLengthMin - mode_.height);
+
+ return vblank;
}
uint32_t CamHelperImx477::GainCode(double gain) const
diff --git a/src/ipa/raspberrypi/cam_helper_ov5647.cpp b/src/ipa/raspberrypi/cam_helper_ov5647.cpp
index ff37779c..53ac3c3b 100644
--- a/src/ipa/raspberrypi/cam_helper_ov5647.cpp
+++ b/src/ipa/raspberrypi/cam_helper_ov5647.cpp
@@ -16,7 +16,7 @@ class CamHelperOv5647 : public CamHelper
{
public:
CamHelperOv5647();
- uint32_t GetVBlanking(double exposure) const override;
+ uint32_t GetVBlanking(double exposure, double maxFps) const override;
uint32_t GainCode(double gain) const override;
double Gain(uint32_t gain_code) const override;
void GetDelays(int &exposure_delay, int &gain_delay) const override;
@@ -27,6 +27,8 @@ public:
private:
/* Smallest difference between the frame length and integration time. */
static constexpr int frameIntegrationDiff = 4;
+ /* Largest possible frame length. */
+ static constexpr int maxFrameLength = 0xffff;
};
/*
@@ -39,12 +41,20 @@ CamHelperOv5647::CamHelperOv5647()
{
}
-uint32_t CamHelperOv5647::GetVBlanking(double exposure) const
+uint32_t CamHelperOv5647::GetVBlanking(double exposure, double maxFps) const
{
+ uint32_t frameLengthMin, vblank;
uint32_t exposureLines = ExposureLines(exposure);
- return std::max<uint32_t>(mode_.height, exposureLines) -
- mode_.height + frameIntegrationDiff;
+ vblank = std::max<uint32_t>(mode_.height, exposureLines) -
+ mode_.height + frameIntegrationDiff;
+
+ /* Limit the vblank to the maximum framerate requested. */
+ frameLengthMin = std::min<uint32_t>(1e9 / (mode_.line_length * maxFps),
+ maxFrameLength);
+ vblank = std::max(vblank, frameLengthMin - mode_.height);
+
+ return vblank;
}
uint32_t CamHelperOv5647::GainCode(double gain) const
diff --git a/src/ipa/raspberrypi/raspberrypi.cpp b/src/ipa/raspberrypi/raspberrypi.cpp
index 104727ea..3a2cc16e 100644
--- a/src/ipa/raspberrypi/raspberrypi.cpp
+++ b/src/ipa/raspberrypi/raspberrypi.cpp
@@ -136,6 +136,12 @@ private:
/* LS table allocation passed in from the pipeline handler. */
uint32_t lsTableHandle_;
void *lsTable_;
+
+ /*
+ * Have some defaults here, but eventually it should come from the
+ * application via a Request, or perhaps stream configuration.
+ */
+ static constexpr double fpsMax = 30.0;
};
int IPARPi::init(const IPASettings &settings)
@@ -795,7 +801,7 @@ void IPARPi::applyAGC(const struct AgcStatus *agcStatus)
int32_t gain_code = helper_->GainCode(agcStatus->analogue_gain);
int32_t exposure_lines = helper_->ExposureLines(agcStatus->shutter_time);
- int32_t vblanking = helper_->GetVBlanking(agcStatus->shutter_time);
+ int32_t vblanking = helper_->GetVBlanking(agcStatus->shutter_time, fpsMax);
if (unicam_ctrls_.find(V4L2_CID_ANALOGUE_GAIN) == unicam_ctrls_.end()) {
LOG(IPARPI, Error) << "Can't find analogue gain control";
--
2.17.1
More information about the libcamera-devel
mailing list