[libcamera-devel,v2,4/6] libcamera: colorspace: Adjust colorspace of YUV streams
diff mbox series

Message ID 20220824162425.71087-5-umang.jain@ideasonboard.com
State Superseded
Delegated to: Umang Jain
Headers show
Series
  • Colorspace adjustments and gstreamer mappings
Related show

Commit Message

Umang Jain Aug. 24, 2022, 4:24 p.m. UTC
If a YUV stream is requested with no Y'CbCr encoding, we need to adjust
it to provide a Y'CbCr encoding. Depending on the transfer function and
primaries specified, a Y'CbCr encoding is picked up.

Signed-off-by: Umang Jain <umang.jain@ideasonboard.com>
---
 include/libcamera/color_space.h |  7 ++++++
 src/libcamera/camera.cpp        |  7 ++++++
 src/libcamera/color_space.cpp   | 42 +++++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+)

Patch
diff mbox series

diff --git a/include/libcamera/color_space.h b/include/libcamera/color_space.h
index 8030a264..3ee1d28f 100644
--- a/include/libcamera/color_space.h
+++ b/include/libcamera/color_space.h
@@ -12,6 +12,9 @@ 
 
 namespace libcamera {
 
+class CameraConfiguration;
+struct StreamConfiguration;
+
 class ColorSpace
 {
 public:
@@ -59,6 +62,10 @@  public:
 
 	std::string toString() const;
 	static std::string toString(const std::optional<ColorSpace> &colorSpace);
+
+private:
+	friend class CameraConfiguration;
+	void adjust(const StreamConfiguration &cfg);
 };
 
 bool operator==(const ColorSpace &lhs, const ColorSpace &rhs);
diff --git a/src/libcamera/camera.cpp b/src/libcamera/camera.cpp
index a5c3aabe..cdf3c112 100644
--- a/src/libcamera/camera.cpp
+++ b/src/libcamera/camera.cpp
@@ -383,6 +383,13 @@  CameraConfiguration::Status CameraConfiguration::validateColorSpaces(ColorSpaceF
 		}
 	}
 
+	if (config_[index].colorSpace) {
+		ColorSpace oldColorspace = config_[index].colorSpace.value();
+		config_[index].colorSpace->adjust(config_[index]);
+		if (oldColorspace != config_[index].colorSpace)
+			status = Adjusted;
+	}
+
 	if (index < 0 || !(flags & ColorSpaceFlag::StreamsShareColorSpace))
 		return status;
 
diff --git a/src/libcamera/color_space.cpp b/src/libcamera/color_space.cpp
index cb47acf9..7beddcbc 100644
--- a/src/libcamera/color_space.cpp
+++ b/src/libcamera/color_space.cpp
@@ -13,6 +13,10 @@ 
 #include <sstream>
 #include <utility>
 
+#include <libcamera/stream.h>
+
+#include "libcamera/internal/formats.h"
+
 /**
  * \file color_space.h
  * \brief Class and enums to represent color spaces
@@ -203,6 +207,44 @@  std::string ColorSpace::toString() const
 	return ss.str();
 }
 
+/**
+ * \brief Adjust the colorspace depending on the stream configuration
+ * \param[in] config Stream configuration
+ *
+ * This function adjust the stream's colorspace depending on various factors
+ * as reflected by the \a config.
+ *
+ * - If the stream's colorspace consists a YUV stream and has no Y'Cbcr
+ *   encoding specified, the Y'Cbcr encoding is updated based on the transfer
+ *   function and primaries fields.
+ */
+void ColorSpace::adjust(const StreamConfiguration &config)
+{
+	ColorSpace *cs = this;
+	bool isYUV = (PixelFormatInfo::info(config.pixelFormat).colourEncoding ==
+		      PixelFormatInfo::ColourEncodingYUV);
+
+	if (isYUV && cs->ycbcrEncoding == YcbcrEncoding::None) {
+		if (cs->transferFunction == TransferFunction::Rec709) {
+			switch (cs->primaries) {
+			/* Raw should never happen */
+			case Primaries::Raw:
+			case Primaries::Smpte170m:
+				cs->ycbcrEncoding = YcbcrEncoding::Rec601;
+				break;
+			case Primaries::Rec709:
+				cs->ycbcrEncoding = YcbcrEncoding::Rec709;
+				break;
+			case Primaries::Rec2020:
+				cs->ycbcrEncoding = YcbcrEncoding::Rec2020;
+				break;
+			}
+		} else if (cs->transferFunction == TransferFunction::Srgb) {
+			cs->ycbcrEncoding = YcbcrEncoding::Rec601;
+		}
+	}
+}
+
 /**
  * \brief Assemble and return a readable string representation of an
  * optional ColorSpace