diff --git a/src/ipa/libipa/camera_sensor_helper.cpp b/src/ipa/libipa/camera_sensor_helper.cpp
index 1a90343c00..3da69bf17b 100644
--- a/src/ipa/libipa/camera_sensor_helper.cpp
+++ b/src/ipa/libipa/camera_sensor_helper.cpp
@@ -76,6 +76,16 @@ namespace ipa {
  * \return The black level of the sensor, or std::nullopt if not known
  */
 
+/**
+ * \fn CameraSensorHelper::exposureMargin()
+ * \brief Fetch the exposure margin of the sensor
+ *
+ * This function returns the exposure margin of the sensor, in lines, which
+ * is the minimum difference between the integration time and frame length.
+ *
+ * \return The exposure margin of the sensor, or std::nullopt if not know
+ */
+
 /**
  * \brief Compute gain code from the analogue gain absolute value
  * \param[in] gain The real gain to pass
@@ -229,6 +239,12 @@ double CameraSensorHelper::quantizeGain(double _gain, double *quantizationGain)
  * sensor specific. Use this variable to store the values at init time.
  */
 
+/**
+ * \var CameraSensorHelper::exposureMargin_
+ * \brief The smallest margin between the integration time and the frame length
+ * in lines
+ */
+
 /**
  * \class CameraSensorHelperFactoryBase
  * \brief Base class for camera sensor helper factories
@@ -385,6 +401,7 @@ public:
 	{
 		/* Power-on default value: 168 at 12bits. */
 		blackLevel_ = 2688;
+		exposureMargin_ = 4;
 	}
 
 	uint32_t gainCode(double gain) const override
@@ -474,6 +491,11 @@ REGISTER_CAMERA_SENSOR_HELPER("ar0144", CameraSensorHelperAr0144)
 class CameraSensorHelperAr0521 : public CameraSensorHelper
 {
 public:
+	CameraSensorHelperAr0521()
+	{
+		exposureMargin_ = 4;
+	}
+
 	uint32_t gainCode(double gain) const override
 	{
 		gain = std::clamp(gain, 1.0, 15.5);
@@ -504,6 +526,7 @@ public:
 		/* From datasheet: 64 at 10bits. */
 		blackLevel_ = 4096;
 		gain_ = AnalogueGainLinear{ 100, 0, 0, 1024 };
+		exposureMargin_ = 4;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("gc05a2", CameraSensorHelperGc05a2)
@@ -516,6 +539,7 @@ public:
 		/* From datasheet: 64 at 10bits. */
 		blackLevel_ = 4096;
 		gain_ = AnalogueGainLinear{ 100, 0, 0, 1024 };
+		exposureMargin_ = 16;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("gc08a3", CameraSensorHelperGc08a3)
@@ -526,6 +550,7 @@ public:
 	CameraSensorHelperHm1246()
 	{
 		gain_ = AnalogueGainLinear{ 1, 16, 0, 16 };
+		exposureMargin_ = 2;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("hm1246", CameraSensorHelperHm1246)
@@ -538,6 +563,7 @@ public:
 		/* From datasheet: 64 at 10bits. */
 		blackLevel_ = 4096;
 		gain_ = AnalogueGainLinear{ 0, 512, -1, 512 };
+		exposureMargin_ = 10;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("imx214", CameraSensorHelperImx214)
@@ -550,6 +576,7 @@ public:
 		/* From datasheet: 64 at 10bits. */
 		blackLevel_ = 4096;
 		gain_ = AnalogueGainLinear{ 0, 256, -1, 256 };
+		exposureMargin_ = 4;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("imx219", CameraSensorHelperImx219)
@@ -562,6 +589,7 @@ public:
 		/* From datasheet: 0x40 at 10bits. */
 		blackLevel_ = 4096;
 		gain_ = AnalogueGainLinear{ 0, 512, -1, 512 };
+		exposureMargin_ = 10;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("imx258", CameraSensorHelperImx258)
@@ -574,6 +602,7 @@ public:
 		/* From datasheet: 0x32 at 10bits. */
 		blackLevel_ = 3200;
 		gain_ = AnalogueGainLinear{ 0, 2048, -1, 2048 };
+		exposureMargin_ = 4;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("imx283", CameraSensorHelperImx283)
@@ -586,6 +615,7 @@ public:
 		/* From datasheet: 0xf0 at 12bits. */
 		blackLevel_ = 3840;
 		gain_ = AnalogueGainExp{ 1.0, expGainDb(0.3) };
+		exposureMargin_ = 2;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("imx290", CameraSensorHelperImx290)
@@ -596,6 +626,11 @@ public:
 	CameraSensorHelperImx296()
 	{
 		gain_ = AnalogueGainExp{ 1.0, expGainDb(0.1) };
+		/*
+		 * The driver doesn't apply any margin. Use the value
+		 * in RPi's CamHelper.
+		 */
+		exposureMargin_ = 4;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("imx296", CameraSensorHelperImx296)
@@ -613,6 +648,7 @@ public:
 		/* From datasheet: 0x32 at 10bits. */
 		blackLevel_ = 3200;
 		gain_ = AnalogueGainExp{ 1.0, expGainDb(0.3) };
+		exposureMargin_ = 9;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("imx335", CameraSensorHelperImx335)
@@ -635,6 +671,7 @@ public:
 	CameraSensorHelperImx415()
 	{
 		gain_ = AnalogueGainExp{ 1.0, expGainDb(0.3) };
+		exposureMargin_ = 8;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("imx415", CameraSensorHelperImx415)
@@ -663,6 +700,7 @@ public:
 	CameraSensorHelperImx477()
 	{
 		gain_ = AnalogueGainLinear{ 0, 1024, -1, 1024 };
+		exposureMargin_ = 22;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("imx477", CameraSensorHelperImx477)
@@ -762,6 +800,7 @@ public:
 		 * This has been validated with some empirical testing only.
 		 */
 		gain_ = AnalogueGainLinear{ 1, 0, 0, 128 };
+		exposureMargin_ = 4;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("ov2685", CameraSensorHelperOv2685)
@@ -774,6 +813,7 @@ public:
 		/* From Linux kernel driver: 0x40 at 10bits. */
 		blackLevel_ = 4096;
 		gain_ = AnalogueGainLinear{ 1, 0, 0, 128 };
+		exposureMargin_ = 8;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("ov2740", CameraSensorHelperOv2740)
@@ -786,6 +826,7 @@ public:
 		/* From datasheet: 0x40 at 12bits. */
 		blackLevel_ = 1024;
 		gain_ = AnalogueGainLinear{ 1, 0, 0, 128 };
+		exposureMargin_ = 4;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("ov4689", CameraSensorHelperOv4689)
@@ -798,6 +839,14 @@ public:
 		/* From datasheet: 0x10 at 10bits. */
 		blackLevel_ = 1024;
 		gain_ = AnalogueGainLinear{ 1, 0, 0, 16 };
+		/*
+		 * Very convoluted in the driver that however applies a margin
+		 * of 4 lines when setting vts.
+		 *
+		 * 	cap_vts = cap_shutter + 4;
+		 * 	ret = ov5640_set_vts(sensor, cap_vts);
+		 */
+		exposureMargin_ = 4;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("ov5640", CameraSensorHelperOv5640)
@@ -808,6 +857,7 @@ public:
 	CameraSensorHelperOv5647()
 	{
 		gain_ = AnalogueGainLinear{ 1, 0, 0, 16 };
+		exposureMargin_ = 4;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("ov5647", CameraSensorHelperOv5647)
@@ -818,6 +868,7 @@ public:
 	CameraSensorHelperOv5670()
 	{
 		gain_ = AnalogueGainLinear{ 1, 0, 0, 128 };
+		exposureMargin_ = 8;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("ov5670", CameraSensorHelperOv5670)
@@ -830,6 +881,7 @@ public:
 		/* From Linux kernel driver: 0x40 at 10bits. */
 		blackLevel_ = 4096;
 		gain_ = AnalogueGainLinear{ 1, 0, 0, 128 };
+		exposureMargin_ = 4;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("ov5675", CameraSensorHelperOv5675)
@@ -841,6 +893,7 @@ public:
 	{
 		blackLevel_ = 1024;
 		gain_ = AnalogueGainLinear{ 1, 0, 0, 16 };
+		exposureMargin_ = 8;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("ov5693", CameraSensorHelperOv5693)
@@ -851,6 +904,7 @@ public:
 	CameraSensorHelperOv64a40()
 	{
 		gain_ = AnalogueGainLinear{ 1, 0, 0, 128 };
+		exposureMargin_ = 32;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("ov64a40", CameraSensorHelperOv64a40)
@@ -867,6 +921,7 @@ public:
 		 * See: https://patchwork.linuxtv.org/project/linux-media/patch/20221106171129.166892-2-nicholas@rothemail.net/#142267
 		 */
 		gain_ = AnalogueGainLinear{ 1, 0, 0, 128 };
+		exposureMargin_ = 4;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("ov8858", CameraSensorHelperOv8858)
@@ -877,6 +932,7 @@ public:
 	CameraSensorHelperOv8865()
 	{
 		gain_ = AnalogueGainLinear{ 1, 0, 0, 128 };
+		exposureMargin_ = 8;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("ov8865", CameraSensorHelperOv8865)
@@ -887,6 +943,7 @@ public:
 	CameraSensorHelperOv13858()
 	{
 		gain_ = AnalogueGainLinear{ 1, 0, 0, 128 };
+		exposureMargin_ = 8;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("ov13858", CameraSensorHelperOv13858)
@@ -899,6 +956,7 @@ public:
 		/* From datasheet: 0x40 at 10bits. */
 		blackLevel_ = 4096;
 		gain_ = AnalogueGainLinear{ 0, 32, -1, 32 };
+		exposureMargin_ = 64;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("vd55g1", CameraSensorHelperVd55g1)
@@ -911,6 +969,7 @@ public:
 		/* From datasheet: 0x40 at 10bits. */
 		blackLevel_ = 4096;
 		gain_ = AnalogueGainLinear{ 0, 32, -1, 32 };
+		exposureMargin_ = 75;
 	}
 };
 REGISTER_CAMERA_SENSOR_HELPER("vd56g3", CameraSensorHelperVd56g3)
diff --git a/src/ipa/libipa/camera_sensor_helper.h b/src/ipa/libipa/camera_sensor_helper.h
index bd3d0beec7..a9e55c832d 100644
--- a/src/ipa/libipa/camera_sensor_helper.h
+++ b/src/ipa/libipa/camera_sensor_helper.h
@@ -27,6 +27,7 @@ public:
 	virtual ~CameraSensorHelper() = default;
 
 	std::optional<int16_t> blackLevel() const { return blackLevel_; }
+	std::optional<uint32_t> exposureMargin() const { return exposureMargin_; }
 	virtual uint32_t gainCode(double gain) const;
 	virtual double gain(uint32_t gainCode) const;
 	double quantizeGain(double gain, double *quantizationGain) const;
@@ -46,6 +47,7 @@ protected:
 
 	std::optional<int16_t> blackLevel_;
 	std::variant<std::monostate, AnalogueGainLinear, AnalogueGainExp> gain_;
+	std::optional<uint32_t> exposureMargin_;
 
 private:
 	LIBCAMERA_DISABLE_COPY_AND_MOVE(CameraSensorHelper)
