[libcamera-devel] [PATCH v4 3/3] qcam: use the OpenGL renderer as NV family YUV format converter

Show Liu show.liu at linaro.org
Fri Aug 21 18:16:02 CEST 2020


qcam: use the OpenGL renderer as NV family YUV format converter

Signed-off-by: Show Liu <show.liu at linaro.org>
---
 src/qcam/main.cpp        |  3 +++
 src/qcam/main_window.cpp |  2 ++
 src/qcam/main_window.h   |  1 +
 src/qcam/viewfinder.cpp  | 46 +++++++++++++++++++++++++++++++++-------
 src/qcam/viewfinder.h    | 10 +++++++++
 5 files changed, 54 insertions(+), 8 deletions(-)

diff --git a/src/qcam/main.cpp b/src/qcam/main.cpp
index b3468cb..a336486 100644
--- a/src/qcam/main.cpp
+++ b/src/qcam/main.cpp
@@ -35,6 +35,9 @@ OptionsParser::Options parseOptions(int argc, char *argv[])
 			 "help");
 	parser.addOption(OptStream, &streamKeyValue,
 			 "Set configuration of a camera stream", "stream", true);
+	parser.addOption(OptRender, OptionString,
+			 "Choose the render type use qt|gles", "render",
+			 ArgumentRequired, "render");
 
 	OptionsParser::Options options = parser.parse(argc, argv);
 	if (options.isSet(OptHelp))
diff --git a/src/qcam/main_window.cpp b/src/qcam/main_window.cpp
index 7503537..26e8a69 100644
--- a/src/qcam/main_window.cpp
+++ b/src/qcam/main_window.cpp
@@ -106,6 +106,8 @@ MainWindow::MainWindow(CameraManager *cm, const OptionsParser::Options &options)
 	connect(&titleTimer_, SIGNAL(timeout()), this, SLOT(updateTitle()));
 
 	viewfinder_ = new ViewFinder(this);
+	if (options_.isSet(OptRender))
+		viewfinder_->setRender(options_[OptRender].toString().c_str());
 	connect(viewfinder_, &ViewFinder::renderComplete,
 		this, &MainWindow::queueRequest);
 	setCentralWidget(viewfinder_);
diff --git a/src/qcam/main_window.h b/src/qcam/main_window.h
index 3d21779..ecc9938 100644
--- a/src/qcam/main_window.h
+++ b/src/qcam/main_window.h
@@ -38,6 +38,7 @@ enum {
 	OptCamera = 'c',
 	OptHelp = 'h',
 	OptStream = 's',
+	OptRender = 'r',
 };
 
 class CaptureRequest
diff --git a/src/qcam/viewfinder.cpp b/src/qcam/viewfinder.cpp
index dcf8a15..7e2b7a7 100644
--- a/src/qcam/viewfinder.cpp
+++ b/src/qcam/viewfinder.cpp
@@ -20,6 +20,7 @@
 #include <libcamera/formats.h>
 
 #include "format_converter.h"
+#include "renderer.h"
 
 static const QMap<libcamera::PixelFormat, QImage::Format> nativeFormats
 {
@@ -34,13 +35,15 @@ static const QMap<libcamera::PixelFormat, QImage::Format> nativeFormats
 };
 
 ViewFinder::ViewFinder(QWidget *parent)
-	: QWidget(parent), buffer_(nullptr)
+	: QWidget(parent), buffer_(nullptr), renderer_(nullptr)
 {
 	icon_ = QIcon(":camera-off.svg");
 }
 
 ViewFinder::~ViewFinder()
 {
+	if (renderer_)
+		delete renderer_;
 }
 
 const QList<libcamera::PixelFormat> &ViewFinder::nativeFormats() const
@@ -59,14 +62,26 @@ int ViewFinder::setFormat(const libcamera::PixelFormat &format,
 	 * the destination image.
 	 */
 	if (!::nativeFormats.contains(format)) {
-		int ret = converter_.configure(format, size);
-		if (ret < 0)
-			return ret;
+		if ((renderType_ == RenderGLES) &&
+		    renderer_->configure(format, size)) {
+			qInfo() << "Using OpenGL shader format conversion from "
+				<< format.toString().c_str();
+		} else {
+			int ret = converter_.configure(format, size);
+			if (ret < 0)
+				return ret;
+
+			image_ = QImage(size, QImage::Format_RGB32);
 
-		image_ = QImage(size, QImage::Format_RGB32);
+			qInfo() << "Using software format conversion from"
+				<< format.toString().c_str();
 
-		qInfo() << "Using software format conversion from"
-			<< format.toString().c_str();
+			if (renderType_ == RenderGLES) {
+				renderType_ = RenderQT;
+				qInfo() << "Using QT rendering due to "
+					<< "OpenGL shader configure failed.";
+			}
+		}
 	} else {
 		qInfo() << "Zero-copy enabled";
 	}
@@ -111,7 +126,11 @@ void ViewFinder::render(libcamera::FrameBuffer *buffer, MappedBuffer *map)
 			 * Otherwise, convert the format and release the frame
 			 * buffer immediately.
 			 */
-			converter_.convert(memory, size, &image_);
+			if (renderType_ == RenderGLES) {
+				renderer_->render(memory);
+				image_ = QImage(renderer_->toImage());
+			} else
+				converter_.convert(memory, size, &image_);
 		}
 	}
 
@@ -179,3 +198,14 @@ QSize ViewFinder::sizeHint() const
 {
 	return size_.isValid() ? size_ : QSize(640, 480);
 }
+
+void ViewFinder::setRender(std::string render_type)
+{
+	if (render_type == "gles") {
+		renderer_ = new Renderer();
+		renderer_->initializeGL();
+		renderType_ = RenderGLES;
+	} else {
+		renderType_ = RenderQT;
+	}
+}
diff --git a/src/qcam/viewfinder.h b/src/qcam/viewfinder.h
index 26a1320..ed09c1e 100644
--- a/src/qcam/viewfinder.h
+++ b/src/qcam/viewfinder.h
@@ -20,6 +20,7 @@
 #include <libcamera/pixel_format.h>
 
 #include "format_converter.h"
+#include "renderer.h"
 
 class QImage;
 
@@ -28,6 +29,11 @@ struct MappedBuffer {
 	size_t size;
 };
 
+enum RenderType {
+	RenderGLES,
+	RenderQT,
+};
+
 class ViewFinder : public QWidget
 {
 	Q_OBJECT
@@ -43,6 +49,7 @@ public:
 	void stop();
 
 	QImage getCurrentImage();
+	void setRender(std::string render_type);
 
 Q_SIGNALS:
 	void renderComplete(libcamera::FrameBuffer *buffer);
@@ -66,6 +73,9 @@ private:
 	libcamera::FrameBuffer *buffer_;
 	QImage image_;
 	QMutex mutex_; /* Prevent concurrent access to image_ */
+
+	Renderer *renderer_; /* OpenGL renderer */
+	RenderType renderType_;
 };
 
 #endif /* __QCAM_VIEWFINDER__ */
-- 
2.20.1



More information about the libcamera-devel mailing list