@@ -153,17 +153,24 @@ module libcamera;
*/
/**
- * \var IPACameraSensorInfo::activeAreaSize
- * \brief The size of the pixel array active area of the sensor
+ * \var IPACameraSensorInfo::activeArea
+ * \brief The active pixel area of the sensor, relative to the physical pixel
+ * array
+ *
+ * The active area rectangle is expressed relative to the top-left corner of the
+ * physical pixel array. It describes the region of the pixel array which
+ * produces valid image data, excluding non-readable and optical black pixels.
+ *
+ * \note New IPA implementations should *not* use this property and instead rely
+ * on coordinates relative to the physical sensor array
*/
/**
* \var IPACameraSensorInfo::analogCrop
- * \brief The portion of the pixel array active area which is read-out and
- * processed
+ * \brief The portion of the pixel array which is read-out and processed
*
* The analog crop rectangle top-left corner is defined as the displacement
- * from the top-left corner of the pixel array active area. The rectangle
+ * from the top-left corner of the physical pixel array. The rectangle
* horizontal and vertical sizes define the portion of the pixel array which
* is read-out and provided to the sensor's internal processing pipeline, before
* any pixel sub-sampling method, such as pixel binning, skipping and averaging
@@ -243,7 +250,7 @@ struct IPACameraSensorInfo {
uint32 bitsPerPixel;
uint32 cfaPattern;
- Size activeAreaSize;
+ Rectangle activeArea;
Rectangle analogCrop;
Size outputSize;
@@ -57,7 +57,7 @@ int Lsc::init(IPAContext &context, const ValueNode &tuningData)
.keys = { "r", "g", "b" },
.numHSamples = kMeshSize,
.numVSamples = kMeshSize,
- .sensorSize = context.sensorInfo.activeAreaSize
+ .sensorSize = context.sensorInfo.activeArea.size()
});
}
@@ -127,7 +127,7 @@ int LensShadingCorrection::init([[maybe_unused]] IPAContext &context,
.keys = { "r", "gr", "gb", "b" },
.numHSamples = RKISP1_CIF_ISP_LSC_SAMPLES_MAX,
.numVSamples = RKISP1_CIF_ISP_LSC_SAMPLES_MAX,
- .sensorSize = context.sensorInfo.activeAreaSize
+ .sensorSize = context.sensorInfo.activeArea.size()
});
}
@@ -561,10 +561,15 @@ void IpaBase::setMode(const IPACameraSensorInfo &sensorInfo)
mode_.bitdepth = sensorInfo.bitsPerPixel;
mode_.width = sensorInfo.outputSize.width;
mode_.height = sensorInfo.outputSize.height;
- mode_.sensorWidth = sensorInfo.activeAreaSize.width;
- mode_.sensorHeight = sensorInfo.activeAreaSize.height;
- mode_.cropX = sensorInfo.analogCrop.x;
- mode_.cropY = sensorInfo.analogCrop.y;
+ mode_.sensorWidth = sensorInfo.activeArea.width;
+ mode_.sensorHeight = sensorInfo.activeArea.height;
+ /*
+ * CameraMode::cropX/Y are defined relative to the active pixel area,
+ * whereas IPACameraSensorInfo::analogCrop is relative to the physical
+ * pixel array. Rebase the crop origin onto the active area.
+ */
+ mode_.cropX = sensorInfo.analogCrop.x - sensorInfo.activeArea.x;
+ mode_.cropY = sensorInfo.analogCrop.y - sensorInfo.activeArea.y;
mode_.pixelRate = sensorInfo.pixelRate;
/*
@@ -883,11 +883,10 @@ int CameraSensorLegacy::sensorInfo(IPACameraSensorInfo *info) const
info->model = model();
/*
- * The active area size is a static property, while the crop
- * rectangle needs to be re-read as it depends on the sensor
- * configuration.
+ * The active area is a static property, while the crop rectangle needs
+ * to be re-read as it depends on the sensor configuration.
*/
- info->activeAreaSize = { activeArea_.width, activeArea_.height };
+ info->activeArea = activeArea_;
/*
* \todo Support for retreiving the crop rectangle is scheduled to
@@ -901,16 +900,6 @@ int CameraSensorLegacy::sensorInfo(IPACameraSensorInfo *info) const
<< "The analogue crop rectangle has been defaulted to the active area size";
}
- /*
- * IPACameraSensorInfo::analogCrop::x and IPACameraSensorInfo::analogCrop::y
- * are defined relatively to the active pixel area, while V4L2's
- * TGT_CROP target is defined in respect to the full pixel array.
- *
- * Compensate it by subtracting the active area offset.
- */
- info->analogCrop.x -= activeArea_.x;
- info->analogCrop.y -= activeArea_.y;
-
/* The bit depth and image size depend on the currently applied format. */
V4L2SubdeviceFormat format{};
ret = subdev_->getFormat(pad_, &format);
@@ -1009,27 +1009,16 @@ int CameraSensorRaw::sensorInfo(IPACameraSensorInfo *info) const
info->model = model();
/*
- * The active area size is a static property, while the crop
- * rectangle needs to be re-read as it depends on the sensor
- * configuration.
+ * The active area is a static property, while the crop rectangle needs
+ * to be re-read as it depends on the sensor configuration.
*/
- info->activeAreaSize = { activeArea_.width, activeArea_.height };
+ info->activeArea = activeArea_;
int ret = subdev_->getSelection(streams_.image.sink, V4L2_SEL_TGT_CROP,
&info->analogCrop);
if (ret)
return ret;
- /*
- * IPACameraSensorInfo::analogCrop::x and IPACameraSensorInfo::analogCrop::y
- * are defined relatively to the active pixel area, while V4L2's
- * TGT_CROP target is defined in respect to the full pixel array.
- *
- * Compensate it by subtracting the active area offset.
- */
- info->analogCrop.x -= activeArea_.x;
- info->analogCrop.y -= activeArea_.y;
-
/* The bit depth and image size depend on the currently applied format. */
V4L2SubdeviceFormat format{};
ret = subdev_->getFormat(streams_.image.source, &format);