[libcamera-devel] [PATCH] qcam: Add JPEG format support

Laurent Pinchart laurent.pinchart at ideasonboard.com
Fri Mar 29 16:27:05 CET 2019


When the camera provides MJPEG, use the QImage JPEG decompression code
to convert that to RGB.

Signed-off-by: Laurent Pinchart <laurent.pinchart at ideasonboard.com>
---
 src/qcam/format_converter.cpp | 16 +++++++++++++++-
 src/qcam/format_converter.h   |  9 ++++++++-
 src/qcam/main_window.cpp      |  2 +-
 src/qcam/viewfinder.cpp       |  4 ++--
 src/qcam/viewfinder.h         |  2 +-
 5 files changed, 27 insertions(+), 6 deletions(-)

diff --git a/src/qcam/format_converter.cpp b/src/qcam/format_converter.cpp
index 6979a054c0ca..bda9057e17b6 100644
--- a/src/qcam/format_converter.cpp
+++ b/src/qcam/format_converter.cpp
@@ -9,6 +9,8 @@
 
 #include <linux/videodev2.h>
 
+#include <QImage>
+
 #include "format_converter.h"
 
 #define RGBSHIFT		8
@@ -45,16 +47,28 @@ int FormatConverter::configure(unsigned int format, unsigned int width,
 		y_pos_ = 0;
 		cb_pos_ = 1;
 		break;
+	case V4L2_PIX_FMT_MJPEG:
+		break;
 	default:
 		return -EINVAL;
 	};
 
+	format_ = format;
 	width_ = width;
 	height_ = height;
 
 	return 0;
 }
 
+void FormatConverter::convert(const unsigned char *src, size_t size,
+			      QImage *dst)
+{
+	if (format_ == V4L2_PIX_FMT_MJPEG)
+		dst->loadFromData(src, size, "JPEG");
+	else
+		convertYUV(src, dst->bits());
+}
+
 static void yuv_to_rgb(int y, int u, int v, int *r, int *g, int *b)
 {
 	int c = y - 16;
@@ -65,7 +79,7 @@ static void yuv_to_rgb(int y, int u, int v, int *r, int *g, int *b)
 	*b = CLIP(( 298 * c + 516 * d           + 128) >> RGBSHIFT);
 }
 
-void FormatConverter::convert(const unsigned char *src, unsigned char *dst)
+void FormatConverter::convertYUV(const unsigned char *src, unsigned char *dst)
 {
 	unsigned int src_x, src_y, dst_x, dst_y;
 	unsigned int src_stride;
diff --git a/src/qcam/format_converter.h b/src/qcam/format_converter.h
index 196064c74f65..396d0bea116a 100644
--- a/src/qcam/format_converter.h
+++ b/src/qcam/format_converter.h
@@ -7,15 +7,22 @@
 #ifndef __QCAM_FORMAT_CONVERTER_H__
 #define __QCAM_FORMAT_CONVERTER_H__
 
+#include <stddef.h>
+
+class QImage;
+
 class FormatConverter
 {
 public:
 	int configure(unsigned int format, unsigned int width,
 		      unsigned int height);
 
-	void convert(const unsigned char *src, unsigned char *dst);
+	void convert(const unsigned char *src, size_t size, QImage *dst);
 
 private:
+	void convertYUV(const unsigned char *src, unsigned char *dst);
+
+	unsigned int format_;
 	unsigned int width_;
 	unsigned int height_;
 	unsigned int y_pos_;
diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp
index a148aa4d117f..fea701422015 100644
--- a/src/qcam/main_window.cpp
+++ b/src/qcam/main_window.cpp
@@ -222,7 +222,7 @@ int MainWindow::display(Buffer *buffer)
 
 	Plane &plane = buffer->planes().front();
 	unsigned char *raw = static_cast<unsigned char *>(plane.mem());
-	viewfinder_->display(raw);
+	viewfinder_->display(raw, buffer->bytesused());
 
 	return 0;
 }
diff --git a/src/qcam/viewfinder.cpp b/src/qcam/viewfinder.cpp
index 5841dc032967..224a227ddd5b 100644
--- a/src/qcam/viewfinder.cpp
+++ b/src/qcam/viewfinder.cpp
@@ -16,9 +16,9 @@ ViewFinder::ViewFinder(QWidget *parent)
 {
 }
 
-void ViewFinder::display(const unsigned char *raw)
+void ViewFinder::display(const unsigned char *raw, size_t size)
 {
-	converter_.convert(raw, image_->bits());
+	converter_.convert(raw, size, image_);
 
 	QPixmap pixmap = QPixmap::fromImage(*image_);
 	setPixmap(pixmap);
diff --git a/src/qcam/viewfinder.h b/src/qcam/viewfinder.h
index df4901699a14..c9ca98913e05 100644
--- a/src/qcam/viewfinder.h
+++ b/src/qcam/viewfinder.h
@@ -20,7 +20,7 @@ public:
 
 	int setFormat(unsigned int format, unsigned int width,
 		      unsigned int height);
-	void display(const unsigned char *rgb);
+	void display(const unsigned char *rgb, size_t size);
 
 private:
 	unsigned int format_;
-- 
Regards,

Laurent Pinchart



More information about the libcamera-devel mailing list