diff --git a/src/qEmbyApp/components/mpvwidget.cpp b/src/qEmbyApp/components/mpvwidget.cpp index 63e9fe3..d68f704 100644 --- a/src/qEmbyApp/components/mpvwidget.cpp +++ b/src/qEmbyApp/components/mpvwidget.cpp @@ -1,6 +1,7 @@ #include "mpvwidget.h" #include "mpvhttpstreamrelay.h" #include "../utils/logredactionutils.h" +#include #include #include #include @@ -9,16 +10,34 @@ #include #include "api/proxymanager.h" +namespace { + +QSurfaceFormat createMpvSurfaceFormat() { + QSurfaceFormat format = QSurfaceFormat::defaultFormat(); + format.setRenderableType(QSurfaceFormat::OpenGL); + format.setVersion(3, 3); + format.setProfile(QSurfaceFormat::CoreProfile); + format.setDepthBufferSize(24); + format.setStencilBufferSize(8); + format.setSwapInterval(1); + format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); + return format; +} + +QString glString(GLenum name) { + const auto *value = reinterpret_cast(glGetString(name)); + return value ? QString::fromLatin1(value) : QStringLiteral(""); +} + +} // namespace + MpvWidget::MpvWidget(QWidget *parent) : QOpenGLWidget(parent), m_mpv_gl(nullptr) { - QSurfaceFormat format = this->format(); - - format.setSwapInterval(1); - this->setFormat(format); + this->setFormat(createMpvSurfaceFormat()); m_controller = new MpvController(this); m_streamRelay = new MpvHttpStreamRelay(this); @@ -108,12 +127,40 @@ void MpvWidget::initializeGL() { initializeOpenGLFunctions(); QOpenGLContext *ctx = QOpenGLContext::currentContext(); - if (ctx && ctx->format().majorVersion() < 2) { + if (!ctx) { + qCritical() << "[MpvWidget] Fatal Error: no current OpenGL context."; + emit errorOccurred(tr("当前环境缺乏必需的 OpenGL 硬件加速支持,视频渲染已禁用。")); + return; + } + + const QSurfaceFormat actualFormat = ctx->format(); + qInfo().noquote() + << QStringLiteral("[MpvWidget] OpenGL context") + << "| requested: desktop OpenGL 3.3 core" + << "| actual:" + << QStringLiteral("%1.%2").arg(actualFormat.majorVersion()).arg(actualFormat.minorVersion()) + << "| profile:" << actualFormat.profile() + << "| renderableType:" << actualFormat.renderableType() + << "| isOpenGLES:" << ctx->isOpenGLES() + << "| vendor:" << glString(GL_VENDOR) + << "| renderer:" << glString(GL_RENDERER) + << "| version:" << glString(GL_VERSION); + + if (actualFormat.majorVersion() < 2) { qCritical() << "Fatal Error: OpenGL version is too low."; emit errorOccurred(tr("当前环境缺乏必需的 OpenGL 硬件加速支持,视频渲染已禁用。")); return; } + if (ctx->isOpenGLES() || actualFormat.majorVersion() < 3) { + qWarning() << "[MpvWidget] OpenGL context cannot safely upload hardware-decoded textures;" + << "disabling MPV hardware decoding to avoid corrupted video" + << "| isOpenGLES:" << ctx->isOpenGLES() + << "| version:" + << QStringLiteral("%1.%2").arg(actualFormat.majorVersion()).arg(actualFormat.minorVersion()); + m_controller->setProperty(QStringLiteral("hwdec"), QStringLiteral("no")); + } + if (m_mpv_gl) { diff --git a/src/qEmbyApp/main.cpp b/src/qEmbyApp/main.cpp index a39f107..fcfa573 100644 --- a/src/qEmbyApp/main.cpp +++ b/src/qEmbyApp/main.cpp @@ -12,6 +12,22 @@ #include "managers/languagemanager.h" #include "managers/logmanager.h" +namespace { + +QSurfaceFormat createDefaultSurfaceFormat() { + QSurfaceFormat format; + format.setRenderableType(QSurfaceFormat::OpenGL); + format.setVersion(3, 3); + format.setProfile(QSurfaceFormat::CoreProfile); + format.setDepthBufferSize(24); + format.setStencilBufferSize(8); + format.setSwapInterval(1); + format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); + return format; +} + +} // namespace + int main(int argc, char *argv[]) { #if defined(Q_OS_LINUX) const QByteArray qpaPlatform = qgetenv("QT_QPA_PLATFORM"); @@ -22,17 +38,7 @@ int main(int argc, char *argv[]) { } #endif - - QSurfaceFormat format; -#if !defined(Q_OS_LINUX) - format.setVersion(3, 3); - format.setProfile(QSurfaceFormat::CoreProfile); -#endif - format.setDepthBufferSize(24); - format.setStencilBufferSize(8); - format.setSwapInterval(1); - format.setSwapBehavior(QSurfaceFormat::DoubleBuffer); - QSurfaceFormat::setDefaultFormat(format); + QSurfaceFormat::setDefaultFormat(createDefaultSurfaceFormat()); QGuiApplication::setAttribute(Qt::AA_DontCreateNativeWidgetSiblings); QApplication a(argc, argv);