|
@@ -0,0 +1,160 @@
|
|
|
+#include "OpenGLWidgetAPI.h"
|
|
|
+
|
|
|
+#include <QApplication>
|
|
|
+#include <QLibrary>
|
|
|
+
|
|
|
+#include "spdlog/spdlog.h"
|
|
|
+
|
|
|
+Image_YUV420P::Image_YUV420P(Image_YUV420P&& other): width(other.width), height(other.height),
|
|
|
+ yData(std::move(other.yData)), uData(std::move(other.uData)), vData(std::move(other.vData))
|
|
|
+{}
|
|
|
+
|
|
|
+Image_YUV420P::Image_YUV420P(const Image_YUV420P& other)
|
|
|
+ : width(other.width), height(other.height),
|
|
|
+ yData(other.yData), uData(other.uData), vData(other.vData)
|
|
|
+{}
|
|
|
+
|
|
|
+Image_YUV420P& Image_YUV420P::operator=(Image_YUV420P&& other)
|
|
|
+{
|
|
|
+ if (this != &other) {
|
|
|
+ width = other.width;
|
|
|
+ height = other.height;
|
|
|
+ yData = std::move(other.yData);
|
|
|
+ uData = std::move(other.uData);
|
|
|
+ vData = std::move(other.vData);
|
|
|
+ }
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+Image_YUV420P& Image_YUV420P::operator=(const Image_YUV420P& other)
|
|
|
+{
|
|
|
+ if (this != &other) {
|
|
|
+ width = other.width;
|
|
|
+ height = other.height;
|
|
|
+ yData = other.yData;
|
|
|
+ uData = other.uData;
|
|
|
+ vData = other.vData;
|
|
|
+ }
|
|
|
+ return *this;
|
|
|
+}
|
|
|
+
|
|
|
+bool Image_YUV420P::isValid() const
|
|
|
+{
|
|
|
+ return width > 0 && height > 0 && !yData.isEmpty() && !uData.isEmpty() && !vData.isEmpty();
|
|
|
+}
|
|
|
+
|
|
|
+void Image_YUV420P::clear()
|
|
|
+{
|
|
|
+ width = 0;
|
|
|
+ height = 0;
|
|
|
+ yData.clear();
|
|
|
+ uData.clear();
|
|
|
+ vData.clear();
|
|
|
+}
|
|
|
+
|
|
|
+/* ----------------------------------------------------------------
|
|
|
+ * OpenGLWidget动态库 API
|
|
|
+ * ---------------------------------------------------------------- */
|
|
|
+
|
|
|
+using funcCreateOpenGLWidget = QWidget* (*)(QWidget*);
|
|
|
+using funcDestroyOpenGLWidget = void (*)(QWidget* widget);
|
|
|
+using funcRefreshRGBAImage = void (*)(QWidget* widget, QImage& image);
|
|
|
+using funcRefreshYUV420Image = void (*)(QWidget* widget, Image_YUV420P* yuvData);
|
|
|
+
|
|
|
+
|
|
|
+funcCreateOpenGLWidget pCreateOpenGLWidget = nullptr;
|
|
|
+funcDestroyOpenGLWidget pDestroyOpenGLWidget = nullptr;
|
|
|
+funcRefreshRGBAImage pRefreshRGBAImage = nullptr;
|
|
|
+funcRefreshYUV420Image pRefreshYUV420Image = nullptr;
|
|
|
+
|
|
|
+static std::atomic_bool isLibraryLoaded = false;
|
|
|
+/* 加载动态库 */
|
|
|
+bool loadOpenGLWidgetLibrary()
|
|
|
+{
|
|
|
+ if(isLibraryLoaded.load())
|
|
|
+ {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ QString libPath = QApplication::applicationDirPath();
|
|
|
+#ifdef QT_DEBUG
|
|
|
+ libPath += "/libOpenGLWidgetd"; // Debug版本
|
|
|
+#else
|
|
|
+ libPath += "/libOpenGLWidget"; // Release版本
|
|
|
+#endif
|
|
|
+
|
|
|
+#ifdef Q_OS_WIN
|
|
|
+ libPath += ".dll";
|
|
|
+#elif defined(Q_OS_MACOS)
|
|
|
+ libPath += ".dylib";
|
|
|
+#elif defined(Q_OS_LINUX)
|
|
|
+ libPath += ".so";
|
|
|
+#endif
|
|
|
+ QLibrary lib(libPath);
|
|
|
+ if (!lib.load())
|
|
|
+ {
|
|
|
+ SPDLOG_ERROR("加载OpenGLWidget动态库失败: {}", libPath.toStdString());
|
|
|
+ SPDLOG_ERROR("错误信息: {}", lib.errorString().toStdString());
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ pCreateOpenGLWidget = reinterpret_cast<funcCreateOpenGLWidget>(lib.resolve("createOpenGLWidget"));
|
|
|
+ pDestroyOpenGLWidget = reinterpret_cast<funcDestroyOpenGLWidget>(lib.resolve("destroyOpenGLWidget"));
|
|
|
+ pRefreshRGBAImage = reinterpret_cast<funcRefreshRGBAImage>(lib.resolve("refreshRGBAImage"));
|
|
|
+ pRefreshYUV420Image = reinterpret_cast<funcRefreshYUV420Image>(lib.resolve("refreshYUV420Image"));
|
|
|
+
|
|
|
+ if(!pCreateOpenGLWidget || !pDestroyOpenGLWidget ||
|
|
|
+ !pRefreshRGBAImage || !pRefreshYUV420Image)
|
|
|
+ {
|
|
|
+ SPDLOG_ERROR("加载OpenGLWidget动态库函数失败");
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ isLibraryLoaded = true;
|
|
|
+ return true;
|
|
|
+}
|
|
|
+
|
|
|
+/* 创建OpenGL窗口,返回QWidget指针 */
|
|
|
+QWidget* createOpenGLWidget(QWidget* parent)
|
|
|
+{
|
|
|
+ if(pCreateOpenGLWidget == nullptr)
|
|
|
+ {
|
|
|
+ SPDLOG_ERROR("OpenGLWidget动态库函数未加载");
|
|
|
+ return nullptr;
|
|
|
+ }
|
|
|
+ return pCreateOpenGLWidget(parent);
|
|
|
+}
|
|
|
+
|
|
|
+/* 销毁OpenGL窗口 */
|
|
|
+void destroyOpenGLWidget(QWidget* widget)
|
|
|
+{
|
|
|
+ if(pDestroyOpenGLWidget == nullptr)
|
|
|
+ {
|
|
|
+ SPDLOG_ERROR("OpenGLWidget动态库函数未加载");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ pDestroyOpenGLWidget(widget);
|
|
|
+}
|
|
|
+
|
|
|
+/* 刷新一帧RGBA图片 */
|
|
|
+void refreshRGBAImage(QWidget* widget, QImage& image)
|
|
|
+{
|
|
|
+ if(pRefreshRGBAImage == nullptr)
|
|
|
+ {
|
|
|
+ SPDLOG_ERROR("OpenGLWidget动态库函数未加载");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ pRefreshRGBAImage(widget, image);
|
|
|
+}
|
|
|
+
|
|
|
+/* 刷新一帧YUV420图片 */
|
|
|
+void refreshYUV420Image(QWidget* widget, Image_YUV420P& yuvData)
|
|
|
+{
|
|
|
+ if(pRefreshYUV420Image == nullptr)
|
|
|
+ {
|
|
|
+ SPDLOG_ERROR("OpenGLWidget动态库函数未加载");
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ pRefreshYUV420Image(widget, &yuvData);
|
|
|
+}
|
|
|
+
|