mirror of
https://git.libcamera.org/libcamera/libcamera.git
synced 2025-07-13 15:29:45 +03:00
pipeline: rpi: Introduce CameraData::CropParams
In preparation for assigning separate crop windows for each stream, add a new CropParams structure that stores the existing ispCrop_ and ispMinCropSize_ as fields. Use a new std::map to store a CropParams structure where the map key is the index of the stream configuration in the CameraConfiguration vector. At preset, only a single CropParams structure will be set at key == 0 to preserve the existing crop handling logic. Signed-off-by: Naushir Patuck <naush@raspberrypi.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo.mondi@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
This commit is contained in:
parent
6bb278c20c
commit
81afca4078
3 changed files with 43 additions and 14 deletions
|
@ -533,6 +533,7 @@ int PipelineHandlerBase::configure(Camera *camera, CameraConfiguration *config)
|
||||||
* Platform specific internal stream configuration. This also assigns
|
* Platform specific internal stream configuration. This also assigns
|
||||||
* external streams which get configured below.
|
* external streams which get configured below.
|
||||||
*/
|
*/
|
||||||
|
data->cropParams_.clear();
|
||||||
ret = data->platformConfigure(rpiConfig);
|
ret = data->platformConfigure(rpiConfig);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -561,10 +562,14 @@ int PipelineHandlerBase::configure(Camera *camera, CameraConfiguration *config)
|
||||||
for (auto const &c : result.controlInfo)
|
for (auto const &c : result.controlInfo)
|
||||||
ctrlMap.emplace(c.first, c.second);
|
ctrlMap.emplace(c.first, c.second);
|
||||||
|
|
||||||
/* Add the ScalerCrop control limits based on the current mode. */
|
const auto cropParamsIt = data->cropParams_.find(0);
|
||||||
Rectangle ispMinCrop = data->scaleIspCrop(Rectangle(data->ispMinCropSize_));
|
if (cropParamsIt != data->cropParams_.end()) {
|
||||||
ctrlMap[&controls::ScalerCrop] = ControlInfo(ispMinCrop, data->sensorInfo_.analogCrop,
|
const CameraData::CropParams &cropParams = cropParamsIt->second;
|
||||||
data->scaleIspCrop(data->ispCrop_));
|
/* Add the ScalerCrop control limits based on the current mode. */
|
||||||
|
Rectangle ispMinCrop = data->scaleIspCrop(Rectangle(cropParams.ispMinCropSize));
|
||||||
|
ctrlMap[&controls::ScalerCrop] = ControlInfo(ispMinCrop, data->sensorInfo_.analogCrop,
|
||||||
|
data->scaleIspCrop(cropParams.ispCrop));
|
||||||
|
}
|
||||||
|
|
||||||
data->controlInfo_ = ControlInfoMap(std::move(ctrlMap), result.controlInfo.idmap());
|
data->controlInfo_ = ControlInfoMap(std::move(ctrlMap), result.controlInfo.idmap());
|
||||||
|
|
||||||
|
@ -1291,8 +1296,10 @@ Rectangle CameraData::scaleIspCrop(const Rectangle &ispCrop) const
|
||||||
void CameraData::applyScalerCrop(const ControlList &controls)
|
void CameraData::applyScalerCrop(const ControlList &controls)
|
||||||
{
|
{
|
||||||
const auto &scalerCrop = controls.get<Rectangle>(controls::ScalerCrop);
|
const auto &scalerCrop = controls.get<Rectangle>(controls::ScalerCrop);
|
||||||
if (scalerCrop) {
|
const auto cropParamsIt = cropParams_.find(0);
|
||||||
|
if (scalerCrop && cropParamsIt != cropParams_.end()) {
|
||||||
Rectangle nativeCrop = *scalerCrop;
|
Rectangle nativeCrop = *scalerCrop;
|
||||||
|
CropParams &cropParams = cropParamsIt->second;
|
||||||
|
|
||||||
if (!nativeCrop.width || !nativeCrop.height)
|
if (!nativeCrop.width || !nativeCrop.height)
|
||||||
nativeCrop = { 0, 0, 1, 1 };
|
nativeCrop = { 0, 0, 1, 1 };
|
||||||
|
@ -1308,12 +1315,12 @@ void CameraData::applyScalerCrop(const ControlList &controls)
|
||||||
* 2. With the same mid-point, if possible.
|
* 2. With the same mid-point, if possible.
|
||||||
* 3. But it can't go outside the sensor area.
|
* 3. But it can't go outside the sensor area.
|
||||||
*/
|
*/
|
||||||
Size minSize = ispMinCropSize_.expandedToAspectRatio(nativeCrop.size());
|
Size minSize = cropParams.ispMinCropSize.expandedToAspectRatio(nativeCrop.size());
|
||||||
Size size = ispCrop.size().expandedTo(minSize);
|
Size size = ispCrop.size().expandedTo(minSize);
|
||||||
ispCrop = size.centeredTo(ispCrop.center()).enclosedIn(Rectangle(sensorInfo_.outputSize));
|
ispCrop = size.centeredTo(ispCrop.center()).enclosedIn(Rectangle(sensorInfo_.outputSize));
|
||||||
|
|
||||||
if (ispCrop != ispCrop_) {
|
if (ispCrop != cropParams.ispCrop) {
|
||||||
ispCrop_ = ispCrop;
|
cropParams.ispCrop = ispCrop;
|
||||||
platformSetIspCrop(ispCrop);
|
platformSetIspCrop(ispCrop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1471,7 +1478,10 @@ void CameraData::fillRequestMetadata(const ControlList &bufferControls, Request
|
||||||
request->metadata().set(controls::SensorTimestamp,
|
request->metadata().set(controls::SensorTimestamp,
|
||||||
bufferControls.get(controls::SensorTimestamp).value_or(0));
|
bufferControls.get(controls::SensorTimestamp).value_or(0));
|
||||||
|
|
||||||
request->metadata().set(controls::ScalerCrop, scaleIspCrop(ispCrop_));
|
const auto cropParamsIt = cropParams_.find(0);
|
||||||
|
if (cropParamsIt != cropParams_.end())
|
||||||
|
request->metadata().set(controls::ScalerCrop,
|
||||||
|
scaleIspCrop(cropParamsIt->second.ispCrop));
|
||||||
}
|
}
|
||||||
|
|
||||||
} /* namespace libcamera */
|
} /* namespace libcamera */
|
||||||
|
|
|
@ -133,8 +133,21 @@ public:
|
||||||
|
|
||||||
/* For handling digital zoom. */
|
/* For handling digital zoom. */
|
||||||
IPACameraSensorInfo sensorInfo_;
|
IPACameraSensorInfo sensorInfo_;
|
||||||
Rectangle ispCrop_; /* crop in ISP (camera mode) pixels */
|
|
||||||
Size ispMinCropSize_;
|
struct CropParams {
|
||||||
|
CropParams(Rectangle ispCrop_, Size ispMinCropSize_)
|
||||||
|
: ispCrop(ispCrop_), ispMinCropSize(ispMinCropSize_)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Crop in ISP (camera mode) pixels */
|
||||||
|
Rectangle ispCrop;
|
||||||
|
/* Minimum crop size in ISP output pixels */
|
||||||
|
Size ispMinCropSize;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Mapping of CropParams keyed by the output stream order in CameraConfiguration */
|
||||||
|
std::map<unsigned int, CropParams> cropParams_;
|
||||||
|
|
||||||
unsigned int dropFrameCount_;
|
unsigned int dropFrameCount_;
|
||||||
|
|
||||||
|
|
|
@ -702,13 +702,19 @@ int Vc4CameraData::platformConfigure(const RPi::RPiCameraConfiguration *rpiConfi
|
||||||
/* Figure out the smallest selection the ISP will allow. */
|
/* Figure out the smallest selection the ISP will allow. */
|
||||||
Rectangle testCrop(0, 0, 1, 1);
|
Rectangle testCrop(0, 0, 1, 1);
|
||||||
isp_[Isp::Input].dev()->setSelection(V4L2_SEL_TGT_CROP, &testCrop);
|
isp_[Isp::Input].dev()->setSelection(V4L2_SEL_TGT_CROP, &testCrop);
|
||||||
ispMinCropSize_ = testCrop.size();
|
|
||||||
|
|
||||||
/* Adjust aspect ratio by providing crops on the input image. */
|
/* Adjust aspect ratio by providing crops on the input image. */
|
||||||
Size size = unicamFormat.size.boundedToAspectRatio(maxSize);
|
Size size = unicamFormat.size.boundedToAspectRatio(maxSize);
|
||||||
ispCrop_ = size.centeredTo(Rectangle(unicamFormat.size).center());
|
Rectangle ispCrop = size.centeredTo(Rectangle(unicamFormat.size).center());
|
||||||
|
|
||||||
platformSetIspCrop(ispCrop_);
|
platformSetIspCrop(ispCrop);
|
||||||
|
/*
|
||||||
|
* Set the scaler crop to the value we are using (scaled to native sensor
|
||||||
|
* coordinates).
|
||||||
|
*/
|
||||||
|
cropParams_.emplace(std::piecewise_construct,
|
||||||
|
std::forward_as_tuple(0),
|
||||||
|
std::forward_as_tuple(ispCrop, testCrop.size()));
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue