summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>2022-08-18 00:30:40 +0300
committerLaurent Pinchart <laurent.pinchart@ideasonboard.com>2022-08-30 10:26:42 +0300
commit4267e0bab86d2c542d2948a2e25e18bb3310fd24 (patch)
treeb9e17a4225abb399d3ff131ba38b7c882a4f8605 /src
parent3fad116f89e0d3497567043cbf6d8c49f1c102db (diff)
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 <laurent.pinchart@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Florian Sylvestre <fsylvestre@baylibre.com>
Diffstat (limited to 'src')
-rw-r--r--src/libcamera/pipeline/rkisp1/rkisp1.cpp38
1 files changed, 33 insertions, 5 deletions
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 <libcamera/base/utils.h>
#include <libcamera/camera.h>
+#include <libcamera/color_space.h>
#include <libcamera/control_ids.h>
#include <libcamera/formats.h>
#include <libcamera/framebuffer.h>
@@ -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> 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;