From 4267e0bab86d2c542d2948a2e25e18bb3310fd24 Mon Sep 17 00:00:00 2001 From: Laurent Pinchart Date: Thu, 18 Aug 2022 00:30:40 +0300 Subject: libcamera: pipeline: rkisp1: Implement color space support Implement color space support in the rkisp1 pipeline handler, in the configuration generation, configuration validation and camera configuration. As all the processing related to the color space is performed in the part of the pipeline shared by all streams, a single color space must cover all stream configurations. This is enforced manually when generating the configuration, and with the validateColorSpaces() helper when validating it. Only the Y'CbCr encoding and quantization range are currently taken into account, and they are programmed through the V4L2 color space API. The primary colors chromaticities and the transfer function need to be configured in the ISP parameters buffer, and thus conveyed to the IPA, but the rkisp1 driver does not currently support tone mapping, so this will be done later. Signed-off-by: Laurent Pinchart Reviewed-by: Paul Elder Reviewed-by: Florian Sylvestre --- src/libcamera/pipeline/rkisp1/rkisp1.cpp | 38 +++++++++++++++++++++++++++----- 1 file changed, 33 insertions(+), 5 deletions(-) (limited to 'src/libcamera/pipeline') diff --git a/src/libcamera/pipeline/rkisp1/rkisp1.cpp b/src/libcamera/pipeline/rkisp1/rkisp1.cpp index 03bbe6b4..25fbf9f1 100644 --- a/src/libcamera/pipeline/rkisp1/rkisp1.cpp +++ b/src/libcamera/pipeline/rkisp1/rkisp1.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -416,11 +417,13 @@ CameraConfiguration::Status RkISP1CameraConfiguration::validate() { const CameraSensor *sensor = data_->sensor_.get(); unsigned int pathCount = data_->selfPath_ ? 2 : 1; - Status status = Valid; + Status status; if (config_.empty()) return Invalid; + status = validateColorSpaces(ColorSpaceFlag::StreamsShareColorSpace); + if (transform != Transform::Identity) { transform = Transform::Identity; status = Adjusted; @@ -547,21 +550,44 @@ CameraConfiguration *PipelineHandlerRkISP1::generateConfiguration(Camera *camera if (roles.empty()) return config; + /* + * As the ISP can't output different color spaces for the main and self + * path, pick a sensible default color space based on the role of the + * first stream and use it for all streams. + */ + std::optional colorSpace; + bool mainPathAvailable = true; bool selfPathAvailable = data->selfPath_; + for (const StreamRole role : roles) { bool useMainPath; switch (role) { - case StreamRole::StillCapture: { + case StreamRole::StillCapture: useMainPath = mainPathAvailable; + /* JPEG encoders typically expect sYCC. */ + if (!colorSpace) + colorSpace = ColorSpace::Sycc; break; - } + case StreamRole::Viewfinder: - case StreamRole::VideoRecording: { useMainPath = !selfPathAvailable; + /* + * sYCC is the YCbCr encoding of sRGB, which is commonly + * used by displays. + */ + if (!colorSpace) + colorSpace = ColorSpace::Sycc; break; - } + + case StreamRole::VideoRecording: + useMainPath = !selfPathAvailable; + /* Rec. 709 is a good default for HD video recording. */ + if (!colorSpace) + colorSpace = ColorSpace::Rec709; + break; + default: LOG(RkISP1, Warning) << "Requested stream role not supported: " << role; @@ -580,6 +606,7 @@ CameraConfiguration *PipelineHandlerRkISP1::generateConfiguration(Camera *camera selfPathAvailable = false; } + cfg.colorSpace = colorSpace; config->addConfiguration(cfg); } @@ -642,6 +669,7 @@ int PipelineHandlerRkISP1::configure(Camera *camera, CameraConfiguration *c) if (ret < 0) return ret; + format.colorSpace = config->at(0).colorSpace; ret = isp_->setFormat(2, &format); if (ret < 0) return ret; -- cgit v1.2.1