mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-13 15:29:45 +03:00
libcamera: camera_sensor: Support SensorConfiguration
Add a class function to the CameraSensor class to apply a full configuration to the sensor. The configuration shall be fully populated and shall apply without modifications to the sensor. Signed-off-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Reviewed-by: Naushir Patuck <naush@raspberrypi.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
1602043e62
commit
f446c23842
2 changed files with 90 additions and 0 deletions
|
@ -29,6 +29,7 @@ namespace libcamera {
|
||||||
class BayerFormat;
|
class BayerFormat;
|
||||||
class CameraLens;
|
class CameraLens;
|
||||||
class MediaEntity;
|
class MediaEntity;
|
||||||
|
class SensorConfiguration;
|
||||||
|
|
||||||
struct CameraSensorProperties;
|
struct CameraSensorProperties;
|
||||||
|
|
||||||
|
@ -58,6 +59,10 @@ public:
|
||||||
Transform transform = Transform::Identity);
|
Transform transform = Transform::Identity);
|
||||||
int tryFormat(V4L2SubdeviceFormat *format) const;
|
int tryFormat(V4L2SubdeviceFormat *format) const;
|
||||||
|
|
||||||
|
int applyConfiguration(const SensorConfiguration &config,
|
||||||
|
Transform transform = Transform::Identity,
|
||||||
|
V4L2SubdeviceFormat *sensorFormat = nullptr);
|
||||||
|
|
||||||
const ControlInfoMap &controls() const;
|
const ControlInfoMap &controls() const;
|
||||||
ControlList getControls(const std::vector<uint32_t> &ids);
|
ControlList getControls(const std::vector<uint32_t> &ids);
|
||||||
int setControls(ControlList *ctrls);
|
int setControls(ControlList *ctrls);
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <libcamera/camera.h>
|
||||||
#include <libcamera/property_ids.h>
|
#include <libcamera/property_ids.h>
|
||||||
|
|
||||||
#include <libcamera/base/utils.h>
|
#include <libcamera/base/utils.h>
|
||||||
|
@ -822,6 +823,90 @@ int CameraSensor::tryFormat(V4L2SubdeviceFormat *format) const
|
||||||
V4L2Subdevice::Whence::TryFormat);
|
V4L2Subdevice::Whence::TryFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Apply a sensor configuration to the camera sensor
|
||||||
|
* \param[in] config The sensor configuration
|
||||||
|
* \param[in] transform The transform to be applied on the sensor.
|
||||||
|
* Defaults to Identity
|
||||||
|
* \param[out] sensorFormat Format applied to the sensor (optional)
|
||||||
|
*
|
||||||
|
* Apply to the camera sensor the configuration \a config.
|
||||||
|
*
|
||||||
|
* \todo The configuration shall be fully populated and if any of the fields
|
||||||
|
* specified cannot be applied exactly, an error code is returned.
|
||||||
|
*
|
||||||
|
* \return 0 if \a config is applied correctly to the camera sensor, a negative
|
||||||
|
* error code otherwise
|
||||||
|
*/
|
||||||
|
int CameraSensor::applyConfiguration(const SensorConfiguration &config,
|
||||||
|
Transform transform,
|
||||||
|
V4L2SubdeviceFormat *sensorFormat)
|
||||||
|
{
|
||||||
|
if (!config.isValid()) {
|
||||||
|
LOG(CameraSensor, Error) << "Invalid sensor configuration";
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<unsigned int> filteredCodes;
|
||||||
|
std::copy_if(mbusCodes_.begin(), mbusCodes_.end(),
|
||||||
|
std::back_inserter(filteredCodes),
|
||||||
|
[&config](unsigned int mbusCode) {
|
||||||
|
BayerFormat bayer = BayerFormat::fromMbusCode(mbusCode);
|
||||||
|
if (bayer.bitDepth == config.bitDepth)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
if (filteredCodes.empty()) {
|
||||||
|
LOG(CameraSensor, Error)
|
||||||
|
<< "Cannot find any format with bit depth "
|
||||||
|
<< config.bitDepth;
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Compute the sensor's data frame size by applying the cropping
|
||||||
|
* rectangle, subsampling and output crop to the sensor's pixel array
|
||||||
|
* size.
|
||||||
|
*
|
||||||
|
* \todo The actual size computation is for now ignored and only the
|
||||||
|
* output size is considered. This implies that resolutions obtained
|
||||||
|
* with two different cropping/subsampling will look identical and
|
||||||
|
* only the first found one will be considered.
|
||||||
|
*/
|
||||||
|
V4L2SubdeviceFormat subdevFormat = {};
|
||||||
|
for (unsigned int code : filteredCodes) {
|
||||||
|
for (const Size &size : sizes(code)) {
|
||||||
|
if (size.width != config.outputSize.width ||
|
||||||
|
size.height != config.outputSize.height)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
subdevFormat.mbus_code = code;
|
||||||
|
subdevFormat.size = size;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!subdevFormat.mbus_code) {
|
||||||
|
LOG(CameraSensor, Error) << "Invalid output size in sensor configuration";
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ret = setFormat(&subdevFormat, transform);
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Return to the caller the format actually applied to the sensor.
|
||||||
|
* This is relevant if transform has changed the bayer pattern order.
|
||||||
|
*/
|
||||||
|
if (sensorFormat)
|
||||||
|
*sensorFormat = subdevFormat;
|
||||||
|
|
||||||
|
/* \todo Handle AnalogCrop. Most sensors do not support set_selection */
|
||||||
|
/* \todo Handle scaling in the digital domain. */
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Retrieve the supported V4L2 controls and their information
|
* \brief Retrieve the supported V4L2 controls and their information
|
||||||
*
|
*
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue