summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gstreamer/gstlibcamera-utils.cpp87
-rw-r--r--src/libcamera/pipeline/rpi/common/pipeline_base.cpp77
2 files changed, 104 insertions, 60 deletions
diff --git a/src/gstreamer/gstlibcamera-utils.cpp b/src/gstreamer/gstlibcamera-utils.cpp
index 79f71246..732987ef 100644
--- a/src/gstreamer/gstlibcamera-utils.cpp
+++ b/src/gstreamer/gstlibcamera-utils.cpp
@@ -254,52 +254,50 @@ gst_format_to_pixel_format(GstVideoFormat gst_format)
return PixelFormat{};
}
+static const struct {
+ PixelFormat format;
+ const gchar *name;
+} bayer_map[]{
+ { formats::SBGGR8, "bggr" },
+ { formats::SGBRG8, "gbrg" },
+ { formats::SGRBG8, "grbg" },
+ { formats::SRGGB8, "rggb" },
+ { formats::SBGGR10, "bggr10le" },
+ { formats::SGBRG10, "gbrg10le" },
+ { formats::SGRBG10, "grbg10le" },
+ { formats::SRGGB10, "rggb10le" },
+ { formats::SBGGR12, "bggr12le" },
+ { formats::SGBRG12, "gbrg12le" },
+ { formats::SGRBG12, "grbg12le" },
+ { formats::SRGGB12, "rggb12le" },
+ { formats::SBGGR14, "bggr14le" },
+ { formats::SGBRG14, "gbrg14le" },
+ { formats::SGRBG14, "grbg14le" },
+ { formats::SRGGB14, "rggb14le" },
+ { formats::SBGGR16, "bggr16le" },
+ { formats::SGBRG16, "gbrg16le" },
+ { formats::SGRBG16, "grbg16le" },
+ { formats::SRGGB16, "rggb16le" },
+};
+
static const gchar *
-bayer_format_to_string(int format)
+bayer_format_to_string(PixelFormat format)
{
- switch (format) {
- case formats::SBGGR8:
- return "bggr";
- case formats::SGBRG8:
- return "gbrg";
- case formats::SGRBG8:
- return "grbg";
- case formats::SRGGB8:
- return "rggb";
- case formats::SBGGR10:
- return "bggr10le";
- case formats::SGBRG10:
- return "gbrg10le";
- case formats::SGRBG10:
- return "grbg10le";
- case formats::SRGGB10:
- return "rggb10le";
- case formats::SBGGR12:
- return "bggr12le";
- case formats::SGBRG12:
- return "gbrg12le";
- case formats::SGRBG12:
- return "grbg12le";
- case formats::SRGGB12:
- return "rggb12le";
- case formats::SBGGR14:
- return "bggr14le";
- case formats::SGBRG14:
- return "gbrg14le";
- case formats::SGRBG14:
- return "grbg14le";
- case formats::SRGGB14:
- return "rggb14le";
- case formats::SBGGR16:
- return "bggr16le";
- case formats::SGBRG16:
- return "gbrg16le";
- case formats::SGRBG16:
- return "grbg16le";
- case formats::SRGGB16:
- return "rggb16le";
+ for (auto &b : bayer_map) {
+ if (b.format == format)
+ return b.name;
}
- return NULL;
+ return nullptr;
+}
+
+static PixelFormat
+bayer_format_from_string(const gchar *name)
+{
+ for (auto &b : bayer_map) {
+ if (strcmp(b.name, name) == 0)
+ return b.format;
+ }
+ return PixelFormat{};
}
static GstStructure *
@@ -474,6 +472,9 @@ gst_libcamera_configure_stream_from_caps(StreamConfiguration &stream_cfg,
const gchar *format = gst_structure_get_string(s, "format");
gst_format = gst_video_format_from_string(format);
stream_cfg.pixelFormat = gst_format_to_pixel_format(gst_format);
+ } else if (gst_structure_has_name(s, "video/x-bayer")) {
+ const gchar *format = gst_structure_get_string(s, "format");
+ stream_cfg.pixelFormat = bayer_format_from_string(format);
} else if (gst_structure_has_name(s, "image/jpeg")) {
stream_cfg.pixelFormat = formats::MJPEG;
} else {
diff --git a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp
index 267e6bd9..917c45b3 100644
--- a/src/libcamera/pipeline/rpi/common/pipeline_base.cpp
+++ b/src/libcamera/pipeline/rpi/common/pipeline_base.cpp
@@ -181,12 +181,14 @@ CameraConfiguration::Status RPiCameraConfiguration::validate()
rawStreams_.clear();
outStreams_.clear();
+ unsigned int rawStreamIndex = 0;
+ unsigned int outStreamIndex = 0;
- for (const auto &[index, cfg] : utils::enumerate(config_)) {
+ for (auto &cfg : config_) {
if (PipelineHandlerBase::isRaw(cfg.pixelFormat))
- rawStreams_.emplace_back(index, &cfg);
+ rawStreams_.emplace_back(rawStreamIndex++, &cfg);
else
- outStreams_.emplace_back(index, &cfg);
+ outStreams_.emplace_back(outStreamIndex++, &cfg);
}
/* Sort the streams so the highest resolution is first. */
@@ -565,10 +567,24 @@ int PipelineHandlerBase::configure(Camera *camera, CameraConfiguration *config)
const auto cropParamsIt = data->cropParams_.find(0);
if (cropParamsIt != data->cropParams_.end()) {
const CameraData::CropParams &cropParams = cropParamsIt->second;
- /* Add the ScalerCrop control limits based on the current mode. */
+ /*
+ * Add the ScalerCrop control limits based on the current mode and
+ * the first configured stream.
+ */
Rectangle ispMinCrop = data->scaleIspCrop(Rectangle(cropParams.ispMinCropSize));
ctrlMap[&controls::ScalerCrop] = ControlInfo(ispMinCrop, data->sensorInfo_.analogCrop,
data->scaleIspCrop(cropParams.ispCrop));
+ if (data->cropParams_.size() == 2) {
+ /*
+ * The control map for rpi::ScalerCrops has the min value
+ * as the default crop for stream 0, max value as the default
+ * value for stream 1.
+ */
+ ctrlMap[&controls::rpi::ScalerCrops] =
+ ControlInfo(data->scaleIspCrop(data->cropParams_.at(0).ispCrop),
+ data->scaleIspCrop(data->cropParams_.at(1).ispCrop),
+ ctrlMap[&controls::ScalerCrop].def());
+ }
}
data->controlInfo_ = ControlInfoMap(std::move(ctrlMap), result.controlInfo.idmap());
@@ -1295,11 +1311,30 @@ Rectangle CameraData::scaleIspCrop(const Rectangle &ispCrop) const
void CameraData::applyScalerCrop(const ControlList &controls)
{
- const auto &scalerCrop = controls.get<Rectangle>(controls::ScalerCrop);
- const auto cropParamsIt = cropParams_.find(0);
- if (scalerCrop && cropParamsIt != cropParams_.end()) {
- Rectangle nativeCrop = *scalerCrop;
- CropParams &cropParams = cropParamsIt->second;
+ const auto &scalerCropRPi = controls.get<Span<const Rectangle>>(controls::rpi::ScalerCrops);
+ const auto &scalerCropCore = controls.get<Rectangle>(controls::ScalerCrop);
+ std::vector<Rectangle> scalerCrops;
+
+ /*
+ * First thing to do is create a vector of crops to apply to each ISP output
+ * based on either controls::ScalerCrop or controls::rpi::ScalerCrops if
+ * present.
+ *
+ * If controls::rpi::ScalerCrops is preset, apply the given crops to the
+ * ISP output streams, indexed by the same order in which they had been
+ * configured. This is not the same as the ISP output index. Otherwise
+ * if controls::ScalerCrop is present, apply the same crop to all ISP
+ * output streams.
+ */
+ for (unsigned int i = 0; i < cropParams_.size(); i++) {
+ if (scalerCropRPi && i < scalerCropRPi->size())
+ scalerCrops.push_back(scalerCropRPi->data()[i]);
+ else if (scalerCropCore)
+ scalerCrops.push_back(*scalerCropCore);
+ }
+
+ for (auto const &[i, scalerCrop] : utils::enumerate(scalerCrops)) {
+ Rectangle nativeCrop = scalerCrop;
if (!nativeCrop.width || !nativeCrop.height)
nativeCrop = { 0, 0, 1, 1 };
@@ -1315,13 +1350,13 @@ void CameraData::applyScalerCrop(const ControlList &controls)
* 2. With the same mid-point, if possible.
* 3. But it can't go outside the sensor area.
*/
- Size minSize = cropParams.ispMinCropSize.expandedToAspectRatio(nativeCrop.size());
+ Size minSize = cropParams_.at(i).ispMinCropSize.expandedToAspectRatio(nativeCrop.size());
Size size = ispCrop.size().expandedTo(minSize);
ispCrop = size.centeredTo(ispCrop.center()).enclosedIn(Rectangle(sensorInfo_.outputSize));
- if (ispCrop != cropParams.ispCrop) {
- cropParams.ispCrop = ispCrop;
- platformSetIspCrop(cropParams.ispIndex, ispCrop);
+ if (ispCrop != cropParams_.at(i).ispCrop) {
+ cropParams_.at(i).ispCrop = ispCrop;
+ platformSetIspCrop(cropParams_.at(i).ispIndex, ispCrop);
}
}
}
@@ -1478,10 +1513,18 @@ void CameraData::fillRequestMetadata(const ControlList &bufferControls, Request
request->metadata().set(controls::SensorTimestamp,
bufferControls.get(controls::SensorTimestamp).value_or(0));
- const auto cropParamsIt = cropParams_.find(0);
- if (cropParamsIt != cropParams_.end())
- request->metadata().set(controls::ScalerCrop,
- scaleIspCrop(cropParamsIt->second.ispCrop));
+ if (cropParams_.size()) {
+ std::vector<Rectangle> crops;
+
+ for (auto const &[k, v] : cropParams_)
+ crops.push_back(scaleIspCrop(v.ispCrop));
+
+ request->metadata().set(controls::ScalerCrop, crops[0]);
+ if (crops.size() > 1) {
+ request->metadata().set(controls::rpi::ScalerCrops,
+ Span<const Rectangle>(crops.data(), crops.size()));
+ }
+ }
}
} /* namespace libcamera */