[libcamera-devel] [PATCH 2/2] qcam: format_converter: Add NV formats support

Paul Elder paul.elder at ideasonboard.com
Sat May 4 22:33:54 CEST 2019


Add support for some NV formats:
- V4L2_PIX_FMT_NV12, V4L2_PIX_FMT_NV21
- V4L2_PIX_FMT_NV16, V4L2_PIX_FMT_NV61
- V4L2_PIX_FMT_NV24, V4L2_PIX_FMT_NV42

Signed-off-by: Paul Elder <paul.elder at ideasonboard.com>
---
 src/qcam/format_converter.cpp | 62 +++++++++++++++++++++++++++++++++++
 src/qcam/format_converter.h   |  7 ++++
 2 files changed, 69 insertions(+)

diff --git a/src/qcam/format_converter.cpp b/src/qcam/format_converter.cpp
index 192767c..ca91c7e 100644
--- a/src/qcam/format_converter.cpp
+++ b/src/qcam/format_converter.cpp
@@ -72,6 +72,42 @@ int FormatConverter::configure(unsigned int format, unsigned int width,
 		y_pos_ = 0;
 		cb_pos_ = 1;
 		break;
+	case V4L2_PIX_FMT_NV12:
+		formatFamily_ = NV;
+		xDownSample_ = 2;
+		yDownSample_ = 2;
+		nvSwap_ = false;
+		break;
+	case V4L2_PIX_FMT_NV21:
+		formatFamily_ = NV;
+		xDownSample_ = 2;
+		yDownSample_ = 2;
+		nvSwap_ = true;
+		break;
+	case V4L2_PIX_FMT_NV16:
+		formatFamily_ = NV;
+		xDownSample_ = 2;
+		yDownSample_ = 1;
+		nvSwap_ = false;
+		break;
+	case V4L2_PIX_FMT_NV61:
+		formatFamily_ = NV;
+		xDownSample_ = 2;
+		yDownSample_ = 1;
+		nvSwap_ = true;
+		break;
+	case V4L2_PIX_FMT_NV24:
+		formatFamily_ = NV;
+		xDownSample_ = 1;
+		yDownSample_ = 1;
+		nvSwap_ = false;
+		break;
+	case V4L2_PIX_FMT_NV42:
+		formatFamily_ = NV;
+		xDownSample_ = 1;
+		yDownSample_ = 1;
+		nvSwap_ = true;
+		break;
 	case V4L2_PIX_FMT_MJPEG:
 		formatFamily_ = MJPEG;
 		break;
@@ -99,6 +135,9 @@ void FormatConverter::convert(const unsigned char *src, size_t size,
 	case RGB:
 		convertRGB(src, dst->bits());
 		break;
+	case NV:
+		convertNV(src, dst->bits());
+		break;
 	};
 }
 
@@ -171,3 +210,26 @@ void FormatConverter::convertYUV(const unsigned char *src, unsigned char *dst)
 		}
 	}
 }
+
+void FormatConverter::convertNV(const unsigned char *src, unsigned char *dst)
+{
+	unsigned int i, j;
+	int r, g, b, y, cr, cb, loc;
+
+	for (j = 0; j < height_; j++) {
+		for (i = 0; i < width_; i++) {
+			y = src[j * width_ + i];
+			loc = height_ * width_ +
+			      (j / yDownSample_) * width_ * 2 / xDownSample_ +
+			      (i & -xDownSample_) * 2 / xDownSample_;
+			cb = nvSwap_ ? src[loc + 1] : src[loc];
+			cr = nvSwap_ ? src[loc] : src[loc + 1];
+
+			yuv_to_rgb(y, cb, cr, &r, &g, &b);
+			dst[j * width_ * 4 + i * 4 + 0] = b;
+			dst[j * width_ * 4 + i * 4 + 1] = g;
+			dst[j * width_ * 4 + i * 4 + 2] = r;
+			dst[j * width_ * 4 + i * 4 + 3] = 0xff;
+		}
+	}
+}
diff --git a/src/qcam/format_converter.h b/src/qcam/format_converter.h
index 9820982..48af0fc 100644
--- a/src/qcam/format_converter.h
+++ b/src/qcam/format_converter.h
@@ -16,6 +16,7 @@ class FormatConverter
 public:
 	enum formatFamily {
 		MJPEG,
+		NV,
 		RGB,
 		YUV,
 	};
@@ -26,6 +27,7 @@ public:
 	void convert(const unsigned char *src, size_t size, QImage *dst);
 
 private:
+	void convertNV(const unsigned char *src, unsigned char *dst);
 	void convertRGB(const unsigned char *src, unsigned char *dst);
 	void convertYUV(const unsigned char *src, unsigned char *dst);
 
@@ -35,6 +37,11 @@ private:
 
 	enum formatFamily formatFamily_;
 
+	/* NV parameters */
+	unsigned int xDownSample_;
+	unsigned int yDownSample_;
+	bool nvSwap_;
+
 	/* RGB parameters */
 	unsigned int bpp_;
 	unsigned int r_pos_;
-- 
2.20.1



More information about the libcamera-devel mailing list