[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