[libcamera-devel] qcam: format_converter: Add RGB formats support

Message ID 20190502162723.30511-1-laurent.pinchart@ideasonboard.com
State Accepted
Commit 28382ff2b181441334f2ccbb3ce82ae491dcc771
Headers show
Series
  • [libcamera-devel] qcam: format_converter: Add RGB formats support
Related show

Commit Message

Laurent Pinchart May 2, 2019, 4:27 p.m. UTC
Add support for the RGB format supported by VIMC (V4L2_PIX_FMT_BGR24,
V4L2_PIX_FMT_RGB24 and V4L2_PIX_FMT_ARGB32).

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
---
 src/qcam/format_converter.cpp | 52 ++++++++++++++++++++++++++++++++++-
 src/qcam/format_converter.h   |  8 ++++++
 2 files changed, 59 insertions(+), 1 deletion(-)

Comments

Paul Elder May 3, 2019, 10:05 p.m. UTC | #1
Hi Laurent,

Thank you for the patch.

On Thu, May 02, 2019 at 07:27:23PM +0300, Laurent Pinchart wrote:
> Add support for the RGB format supported by VIMC (V4L2_PIX_FMT_BGR24,
> V4L2_PIX_FMT_RGB24 and V4L2_PIX_FMT_ARGB32).
> 
> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>

Looks good to me.

Reviewed-by: Paul Elder <paul.elder@ideasonboard.com>

> ---
>  src/qcam/format_converter.cpp | 52 ++++++++++++++++++++++++++++++++++-
>  src/qcam/format_converter.h   |  8 ++++++
>  2 files changed, 59 insertions(+), 1 deletion(-)
> 
> diff --git a/src/qcam/format_converter.cpp b/src/qcam/format_converter.cpp
> index bda9057e17b6..d9088c38f0d4 100644
> --- a/src/qcam/format_converter.cpp
> +++ b/src/qcam/format_converter.cpp
> @@ -31,23 +31,49 @@ int FormatConverter::configure(unsigned int format, unsigned int width,
>  			       unsigned int height)
>  {
>  	switch (format) {
> +	case V4L2_PIX_FMT_BGR24:
> +		yuv_ = false;
> +		r_pos_ = 2;
> +		g_pos_ = 1;
> +		b_pos_ = 0;
> +		bpp_ = 3;
> +		break;
> +	case V4L2_PIX_FMT_RGB24:
> +		yuv_ = false;
> +		r_pos_ = 0;
> +		g_pos_ = 1;
> +		b_pos_ = 2;
> +		bpp_ = 3;
> +		break;
> +	case V4L2_PIX_FMT_ARGB32:
> +		yuv_ = false;
> +		r_pos_ = 1;
> +		g_pos_ = 2;
> +		b_pos_ = 3;
> +		bpp_ = 4;
> +		break;
>  	case V4L2_PIX_FMT_VYUY:
> +		yuv_ = true;
>  		y_pos_ = 1;
>  		cb_pos_ = 2;
>  		break;
>  	case V4L2_PIX_FMT_YVYU:
> +		yuv_ = true;
>  		y_pos_ = 0;
>  		cb_pos_ = 3;
>  		break;
>  	case V4L2_PIX_FMT_UYVY:
> +		yuv_ = true;
>  		y_pos_ = 1;
>  		cb_pos_ = 0;
>  		break;
>  	case V4L2_PIX_FMT_YUYV:
> +		yuv_ = true;
>  		y_pos_ = 0;
>  		cb_pos_ = 1;
>  		break;
>  	case V4L2_PIX_FMT_MJPEG:
> +		yuv_ = false;
>  		break;
>  	default:
>  		return -EINVAL;
> @@ -65,8 +91,32 @@ void FormatConverter::convert(const unsigned char *src, size_t size,
>  {
>  	if (format_ == V4L2_PIX_FMT_MJPEG)
>  		dst->loadFromData(src, size, "JPEG");
> -	else
> +	else if (yuv_)
>  		convertYUV(src, dst->bits());
> +	else
> +		convertRGB(src, dst->bits());
> +}
> +
> +void FormatConverter::convertRGB(const unsigned char *src, unsigned char *dst)
> +{
> +	unsigned int x, y;
> +	int r, g, b;
> +
> +	for (y = 0; y < height_; y++) {
> +		for (x = 0; x < width_; x++) {
> +			r = src[bpp_ * x + r_pos_];
> +			g = src[bpp_ * x + g_pos_];
> +			b = src[bpp_ * x + b_pos_];
> +
> +			dst[4 * x + 0] = b;
> +			dst[4 * x + 1] = g;
> +			dst[4 * x + 2] = r;
> +			dst[4 * x + 3] = 0xff;
> +		}
> +
> +		src += width_ * bpp_;
> +		dst += width_ * 4;
> +	}
>  }
>  
>  static void yuv_to_rgb(int y, int u, int v, int *r, int *g, int *b)
> diff --git a/src/qcam/format_converter.h b/src/qcam/format_converter.h
> index 396d0bea116a..76cd9f1cab56 100644
> --- a/src/qcam/format_converter.h
> +++ b/src/qcam/format_converter.h
> @@ -20,11 +20,19 @@ public:
>  	void convert(const unsigned char *src, size_t size, QImage *dst);
>  
>  private:
> +	void convertRGB(const unsigned char *src, unsigned char *dst);
>  	void convertYUV(const unsigned char *src, unsigned char *dst);
>  
>  	unsigned int format_;
>  	unsigned int width_;
>  	unsigned int height_;
> +
> +	unsigned int bpp_;
> +	unsigned int r_pos_;
> +	unsigned int g_pos_;
> +	unsigned int b_pos_;
> +
> +	bool yuv_;
>  	unsigned int y_pos_;
>  	unsigned int cb_pos_;
>  };
> -- 
> Regards,
> 
> Laurent Pinchart
> 
> _______________________________________________
> libcamera-devel mailing list
> libcamera-devel@lists.libcamera.org
> https://lists.libcamera.org/listinfo/libcamera-devel

Patch

diff --git a/src/qcam/format_converter.cpp b/src/qcam/format_converter.cpp
index bda9057e17b6..d9088c38f0d4 100644
--- a/src/qcam/format_converter.cpp
+++ b/src/qcam/format_converter.cpp
@@ -31,23 +31,49 @@  int FormatConverter::configure(unsigned int format, unsigned int width,
 			       unsigned int height)
 {
 	switch (format) {
+	case V4L2_PIX_FMT_BGR24:
+		yuv_ = false;
+		r_pos_ = 2;
+		g_pos_ = 1;
+		b_pos_ = 0;
+		bpp_ = 3;
+		break;
+	case V4L2_PIX_FMT_RGB24:
+		yuv_ = false;
+		r_pos_ = 0;
+		g_pos_ = 1;
+		b_pos_ = 2;
+		bpp_ = 3;
+		break;
+	case V4L2_PIX_FMT_ARGB32:
+		yuv_ = false;
+		r_pos_ = 1;
+		g_pos_ = 2;
+		b_pos_ = 3;
+		bpp_ = 4;
+		break;
 	case V4L2_PIX_FMT_VYUY:
+		yuv_ = true;
 		y_pos_ = 1;
 		cb_pos_ = 2;
 		break;
 	case V4L2_PIX_FMT_YVYU:
+		yuv_ = true;
 		y_pos_ = 0;
 		cb_pos_ = 3;
 		break;
 	case V4L2_PIX_FMT_UYVY:
+		yuv_ = true;
 		y_pos_ = 1;
 		cb_pos_ = 0;
 		break;
 	case V4L2_PIX_FMT_YUYV:
+		yuv_ = true;
 		y_pos_ = 0;
 		cb_pos_ = 1;
 		break;
 	case V4L2_PIX_FMT_MJPEG:
+		yuv_ = false;
 		break;
 	default:
 		return -EINVAL;
@@ -65,8 +91,32 @@  void FormatConverter::convert(const unsigned char *src, size_t size,
 {
 	if (format_ == V4L2_PIX_FMT_MJPEG)
 		dst->loadFromData(src, size, "JPEG");
-	else
+	else if (yuv_)
 		convertYUV(src, dst->bits());
+	else
+		convertRGB(src, dst->bits());
+}
+
+void FormatConverter::convertRGB(const unsigned char *src, unsigned char *dst)
+{
+	unsigned int x, y;
+	int r, g, b;
+
+	for (y = 0; y < height_; y++) {
+		for (x = 0; x < width_; x++) {
+			r = src[bpp_ * x + r_pos_];
+			g = src[bpp_ * x + g_pos_];
+			b = src[bpp_ * x + b_pos_];
+
+			dst[4 * x + 0] = b;
+			dst[4 * x + 1] = g;
+			dst[4 * x + 2] = r;
+			dst[4 * x + 3] = 0xff;
+		}
+
+		src += width_ * bpp_;
+		dst += width_ * 4;
+	}
 }
 
 static void yuv_to_rgb(int y, int u, int v, int *r, int *g, int *b)
diff --git a/src/qcam/format_converter.h b/src/qcam/format_converter.h
index 396d0bea116a..76cd9f1cab56 100644
--- a/src/qcam/format_converter.h
+++ b/src/qcam/format_converter.h
@@ -20,11 +20,19 @@  public:
 	void convert(const unsigned char *src, size_t size, QImage *dst);
 
 private:
+	void convertRGB(const unsigned char *src, unsigned char *dst);
 	void convertYUV(const unsigned char *src, unsigned char *dst);
 
 	unsigned int format_;
 	unsigned int width_;
 	unsigned int height_;
+
+	unsigned int bpp_;
+	unsigned int r_pos_;
+	unsigned int g_pos_;
+	unsigned int b_pos_;
+
+	bool yuv_;
 	unsigned int y_pos_;
 	unsigned int cb_pos_;
 };