[libcamera-devel] [PATCH 09/11] apps: qcam: Add support for IPU3_Y10

Daniel Scally dan.scally at ideasonboard.com
Sun Mar 19 00:40:12 CET 2023


Add support for the IPU3_Y10 format to the FormatConverter.

Signed-off-by: Daniel Scally <dan.scally at ideasonboard.com>
---
 src/apps/qcam/format_converter.cpp | 50 ++++++++++++++++++++++++++++++
 src/apps/qcam/format_converter.h   |  2 ++
 2 files changed, 52 insertions(+)

diff --git a/src/apps/qcam/format_converter.cpp b/src/apps/qcam/format_converter.cpp
index de76b32c..7f5648f3 100644
--- a/src/apps/qcam/format_converter.cpp
+++ b/src/apps/qcam/format_converter.cpp
@@ -169,6 +169,10 @@ int FormatConverter::configure(const libcamera::PixelFormat &format,
 		formatFamily_ = MJPEG;
 		break;
 
+	case libcamera::formats::Y10_IPU3:
+		formatFamily_ = IPU3Packed;
+		break;
+
 	default:
 		return -EINVAL;
 	};
@@ -199,6 +203,9 @@ void FormatConverter::convert(const Image *src, size_t size, QImage *dst)
 	case YUVPlanar:
 		convertYUVPlanar(src, dst->bits());
 		break;
+	case IPU3Packed:
+		convertIPU3Packed(src, dst->bits(), size);
+		break;
 	};
 }
 
@@ -357,3 +364,46 @@ void FormatConverter::convertYUVSemiPlanar(const Image *srcImage, unsigned char
 		}
 	}
 }
+
+void FormatConverter::convertIPU3Packed(const Image *srcImage, unsigned char *dst, size_t size)
+{
+	const unsigned char *src = srcImage->data(0).data();
+	unsigned int bytesprocessed = 0;
+	unsigned int lsb_shift;
+	unsigned int msb_shift;
+	unsigned int index;
+	unsigned int x = 0;
+	uint16_t pixel;
+
+	while (bytesprocessed < size) {
+		for (unsigned int i = 0; i < 25; ++i) {
+			index = (i * 10) / 8;
+			lsb_shift = (i * 10) % 8;
+			msb_shift = 8 - lsb_shift;
+
+			/*
+			 * The IPU3-packed format can result in padding at the
+			 * end of a 32-byte block if the last pixel in a row is
+			 * within that block. Check whether we're on the line's
+			 * last pixel and skip the rest of the block if so.
+			 */
+			if (x == width_) {
+				x = 0;
+				dst += width_ * 4;
+				break;
+			}
+
+			pixel = (((src + bytesprocessed)[index+1] << msb_shift) & 0x3ff)
+			      | (((src + bytesprocessed)[index+0] >> lsb_shift) & 0x3ff);
+
+			dst[4 * x + 0] = (pixel >> 2) & 0xff;
+			dst[4 * x + 1] = (pixel >> 2) & 0xff;
+			dst[4 * x + 2] = (pixel >> 2) & 0xff;
+			dst[4 * x + 3] = 0xff;
+
+			x++;
+		}
+
+		bytesprocessed += 32;
+	}
+}
diff --git a/src/apps/qcam/format_converter.h b/src/apps/qcam/format_converter.h
index 37dbfae2..940f8b6b 100644
--- a/src/apps/qcam/format_converter.h
+++ b/src/apps/qcam/format_converter.h
@@ -31,12 +31,14 @@ private:
 		YUVPacked,
 		YUVPlanar,
 		YUVSemiPlanar,
+		IPU3Packed,
 	};
 
 	void convertRGB(const Image *src, unsigned char *dst);
 	void convertYUVPacked(const Image *src, unsigned char *dst);
 	void convertYUVPlanar(const Image *src, unsigned char *dst);
 	void convertYUVSemiPlanar(const Image *src, unsigned char *dst);
+	void convertIPU3Packed(const Image *src, unsigned char *dst, size_t size);
 
 	libcamera::PixelFormat format_;
 	unsigned int width_;
-- 
2.34.1



More information about the libcamera-devel mailing list