mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-12 23:09:45 +03:00
libcamera: rkisp1: Integrate SensorConfiguration support
Integrate the RkISP1 pipeline handler to support sensor configuration provided by applications through CameraConfiguration::sensorConfig. The SensorConfiguration must be validated on both RkISP1Path (mainPath and selfPath), so the parameters of RkISP1Path::validate() have been updated to include sensorConfig. The camera configuration will be marked as invalid when the sensor configuration is supplied, if: - Invalid sensor configuration (SensorConfiguration::isValid()) - Bit depth not supported by RkISP1 pipeline - Sensor configuration output size is larger than maximum supported sensor's size on RkISP1 pipeline - No matching sensor configuration output size supplied by the sensor Signed-off-by: Umang Jain <umang.jain@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Reviewed-by: Stefan Klug <stefan.klug@ideasonboard.com> Tested-by: Stefan Klug <stefan.klug@ideasonboard.com>
This commit is contained in:
parent
fc761ffe49
commit
047d647452
3 changed files with 80 additions and 12 deletions
|
@ -447,11 +447,12 @@ bool RkISP1CameraConfiguration::fitsAllPaths(const StreamConfiguration &cfg)
|
|||
StreamConfiguration config;
|
||||
|
||||
config = cfg;
|
||||
if (data_->mainPath_->validate(sensor, &config) != Valid)
|
||||
if (data_->mainPath_->validate(sensor, sensorConfig, &config) != Valid)
|
||||
return false;
|
||||
|
||||
config = cfg;
|
||||
if (data_->selfPath_ && data_->selfPath_->validate(sensor, &config) != Valid)
|
||||
if (data_->selfPath_ &&
|
||||
data_->selfPath_->validate(sensor, sensorConfig, &config) != Valid)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -468,6 +469,27 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate()
|
|||
|
||||
status = validateColorSpaces(ColorSpaceFlag::StreamsShareColorSpace);
|
||||
|
||||
/*
|
||||
* Make sure that if a sensor configuration has been requested it
|
||||
* is valid.
|
||||
*/
|
||||
if (sensorConfig) {
|
||||
if (!sensorConfig->isValid()) {
|
||||
LOG(RkISP1, Error)
|
||||
<< "Invalid sensor configuration request";
|
||||
|
||||
return Invalid;
|
||||
}
|
||||
|
||||
unsigned int bitDepth = sensorConfig->bitDepth;
|
||||
if (bitDepth != 8 && bitDepth != 10 && bitDepth != 12) {
|
||||
LOG(RkISP1, Error)
|
||||
<< "Invalid sensor configuration bit depth";
|
||||
|
||||
return Invalid;
|
||||
}
|
||||
}
|
||||
|
||||
/* Cap the number of entries to the available streams. */
|
||||
if (config_.size() > pathCount) {
|
||||
config_.resize(pathCount);
|
||||
|
@ -514,7 +536,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate()
|
|||
/* Try to match stream without adjusting configuration. */
|
||||
if (mainPathAvailable) {
|
||||
StreamConfiguration tryCfg = cfg;
|
||||
if (data_->mainPath_->validate(sensor, &tryCfg) == Valid) {
|
||||
if (data_->mainPath_->validate(sensor, sensorConfig, &tryCfg) == Valid) {
|
||||
mainPathAvailable = false;
|
||||
cfg = tryCfg;
|
||||
cfg.setStream(const_cast<Stream *>(&data_->mainPathStream_));
|
||||
|
@ -524,7 +546,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate()
|
|||
|
||||
if (selfPathAvailable) {
|
||||
StreamConfiguration tryCfg = cfg;
|
||||
if (data_->selfPath_->validate(sensor, &tryCfg) == Valid) {
|
||||
if (data_->selfPath_->validate(sensor, sensorConfig, &tryCfg) == Valid) {
|
||||
selfPathAvailable = false;
|
||||
cfg = tryCfg;
|
||||
cfg.setStream(const_cast<Stream *>(&data_->selfPathStream_));
|
||||
|
@ -535,7 +557,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate()
|
|||
/* Try to match stream allowing adjusting configuration. */
|
||||
if (mainPathAvailable) {
|
||||
StreamConfiguration tryCfg = cfg;
|
||||
if (data_->mainPath_->validate(sensor, &tryCfg) == Adjusted) {
|
||||
if (data_->mainPath_->validate(sensor, sensorConfig, &tryCfg) == Adjusted) {
|
||||
mainPathAvailable = false;
|
||||
cfg = tryCfg;
|
||||
cfg.setStream(const_cast<Stream *>(&data_->mainPathStream_));
|
||||
|
@ -546,7 +568,7 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate()
|
|||
|
||||
if (selfPathAvailable) {
|
||||
StreamConfiguration tryCfg = cfg;
|
||||
if (data_->selfPath_->validate(sensor, &tryCfg) == Adjusted) {
|
||||
if (data_->selfPath_->validate(sensor, sensorConfig, &tryCfg) == Adjusted) {
|
||||
selfPathAvailable = false;
|
||||
cfg = tryCfg;
|
||||
cfg.setStream(const_cast<Stream *>(&data_->selfPathStream_));
|
||||
|
@ -723,7 +745,13 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c)
|
|||
V4L2SubdeviceFormat format = config->sensorFormat();
|
||||
LOG(RkISP1, Debug) << "Configuring sensor with " << format;
|
||||
|
||||
ret = sensor->setFormat(&format, config->combinedTransform());
|
||||
if (config->sensorConfig)
|
||||
ret = sensor->applyConfiguration(*config->sensorConfig,
|
||||
config->combinedTransform(),
|
||||
&format);
|
||||
else
|
||||
ret = sensor->setFormat(&format, config->combinedTransform());
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
|
|
|
@ -251,8 +251,10 @@ RkISP1Path::generateConfiguration(const CameraSensor *sensor, const Size &size,
|
|||
return cfg;
|
||||
}
|
||||
|
||||
CameraConfiguration::Status RkISP1Path::validate(const CameraSensor *sensor,
|
||||
StreamConfiguration *cfg)
|
||||
CameraConfiguration::Status
|
||||
RkISP1Path::validate(const CameraSensor *sensor,
|
||||
std::optional<SensorConfiguration> &sensorConfig,
|
||||
StreamConfiguration *cfg)
|
||||
{
|
||||
const std::vector<unsigned int> &mbusCodes = sensor->mbusCodes();
|
||||
Size resolution = filterSensorResolution(sensor);
|
||||
|
@ -282,9 +284,14 @@ CameraConfiguration::Status RkISP1Path::validate(const CameraSensor *sensor,
|
|||
continue;
|
||||
|
||||
/*
|
||||
* Store the raw format with the highest bits per pixel
|
||||
* for later usage.
|
||||
* If the bits per pixel is supplied from the sensor
|
||||
* configuration, choose a raw format that complies with
|
||||
* it. Otherwise, store the raw format with the highest
|
||||
* bits per pixel for later usage.
|
||||
*/
|
||||
if (sensorConfig && info.bitsPerPixel != sensorConfig->bitDepth)
|
||||
continue;
|
||||
|
||||
if (info.bitsPerPixel > rawBitsPerPixel) {
|
||||
rawBitsPerPixel = info.bitsPerPixel;
|
||||
rawFormat = format;
|
||||
|
@ -297,6 +304,9 @@ CameraConfiguration::Status RkISP1Path::validate(const CameraSensor *sensor,
|
|||
}
|
||||
}
|
||||
|
||||
if (sensorConfig && !found)
|
||||
return CameraConfiguration::Invalid;
|
||||
|
||||
bool isRaw = PixelFormatInfo::info(cfg->pixelFormat).colourEncoding ==
|
||||
PixelFormatInfo::ColourEncodingRAW;
|
||||
|
||||
|
@ -319,11 +329,39 @@ CameraConfiguration::Status RkISP1Path::validate(const CameraSensor *sensor,
|
|||
* size.
|
||||
*/
|
||||
uint32_t mbusCode = formatToMediaBus.at(cfg->pixelFormat);
|
||||
Size rawSize = sensorConfig ? sensorConfig->outputSize
|
||||
: cfg->size;
|
||||
|
||||
V4L2SubdeviceFormat sensorFormat =
|
||||
sensor->getFormat({ mbusCode }, cfg->size);
|
||||
sensor->getFormat({ mbusCode }, rawSize);
|
||||
|
||||
if (sensorConfig &&
|
||||
sensorConfig->outputSize != sensorFormat.size)
|
||||
return CameraConfiguration::Invalid;
|
||||
|
||||
minResolution = sensorFormat.size;
|
||||
maxResolution = sensorFormat.size;
|
||||
} else if (sensorConfig) {
|
||||
/*
|
||||
* We have already ensured 'rawFormat' has the matching bit
|
||||
* depth with sensorConfig.bitDepth hence, only validate the
|
||||
* sensorConfig's output size here.
|
||||
*/
|
||||
Size sensorSize = sensorConfig->outputSize;
|
||||
|
||||
if (sensorSize > resolution)
|
||||
return CameraConfiguration::Invalid;
|
||||
|
||||
uint32_t mbusCode = formatToMediaBus.at(rawFormat);
|
||||
V4L2SubdeviceFormat sensorFormat =
|
||||
sensor->getFormat({ mbusCode }, sensorSize);
|
||||
|
||||
if (sensorFormat.size != sensorSize)
|
||||
return CameraConfiguration::Invalid;
|
||||
|
||||
minResolution = minResolution_.expandedToAspectRatio(sensorSize);
|
||||
maxResolution = maxResolution_.boundedTo(sensorSize)
|
||||
.boundedToAspectRatio(sensorSize);
|
||||
} else {
|
||||
/*
|
||||
* Adjust the size based on the sensor resolution and absolute
|
||||
|
|
|
@ -27,6 +27,7 @@ namespace libcamera {
|
|||
class CameraSensor;
|
||||
class MediaDevice;
|
||||
class V4L2Subdevice;
|
||||
class SensorConfiguration;
|
||||
struct StreamConfiguration;
|
||||
struct V4L2SubdeviceFormat;
|
||||
|
||||
|
@ -44,6 +45,7 @@ public:
|
|||
const Size &resolution,
|
||||
StreamRole role);
|
||||
CameraConfiguration::Status validate(const CameraSensor *sensor,
|
||||
std::optional<SensorConfiguration> &sensorConfig,
|
||||
StreamConfiguration *cfg);
|
||||
|
||||
int configure(const StreamConfiguration &config,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue