diff options
61 files changed, 1087 insertions, 582 deletions
diff --git a/dependencies.yaml b/dependencies.yaml index 9d7513a5b..13ea00551 100644 --- a/dependencies.yaml +++ b/dependencies.yaml @@ -1,7 +1,7 @@ dependencies: ../qtbase: - ref: e0b89899e3c505edbdece60d6a2d2368a7ef9a01 + ref: 370324f6e2f3ce7d250a1c3686918c08da1f8b06 required: true ../qtdeclarative: - ref: eb5aa8d9c18535ecd0aacc42fe3af954faf01c04 + ref: 201f28c7e332bc0cb37a80f4ffff0d473d24455a required: false diff --git a/examples/multimediawidgets/videographicsitem/videoplayer.cpp b/examples/multimediawidgets/videographicsitem/videoplayer.cpp index 39c113fe5..917a71f64 100644 --- a/examples/multimediawidgets/videographicsitem/videoplayer.cpp +++ b/examples/multimediawidgets/videographicsitem/videoplayer.cpp @@ -57,7 +57,7 @@ VideoPlayer::VideoPlayer(QWidget *parent) : QWidget(parent) { m_mediaPlayer = new QMediaPlayer(this, QMediaPlayer::VideoSurface); - const QRect screenGeometry = QApplication::desktop()->screenGeometry(this); + const QSize screenGeometry = screen()->availableSize(); m_videoItem = new QGraphicsVideoItem; m_videoItem->setSize(QSizeF(screenGeometry.width() / 3, screenGeometry.height() / 2)); diff --git a/examples/multimediawidgets/videowidget/main.cpp b/examples/multimediawidgets/videowidget/main.cpp index 319df7b70..9f53f96f5 100644 --- a/examples/multimediawidgets/videowidget/main.cpp +++ b/examples/multimediawidgets/videowidget/main.cpp @@ -55,6 +55,7 @@ #include <QtCore/QCommandLineParser> #include <QtCore/QCommandLineOption> #include <QtCore/QDir> +#include <QScreen> int main(int argc, char *argv[]) { @@ -79,7 +80,7 @@ int main(int argc, char *argv[]) player.setUrl(url); } - const QRect availableGeometry = QApplication::desktop()->availableGeometry(&player); + const QSize availableGeometry = player.screen()->availableSize(); player.resize(availableGeometry.width() / 6, availableGeometry.height() / 4); player.show(); diff --git a/src/gsttools/gstvideoconnector.c b/src/gsttools/gstvideoconnector.c index 7f88a89af..b85f5bdbe 100644 --- a/src/gsttools/gstvideoconnector.c +++ b/src/gsttools/gstvideoconnector.c @@ -116,13 +116,13 @@ gst_video_connector_class_init (GstVideoConnectorClass * klass) gst_video_connector_signals[SIGNAL_RESEND_NEW_SEGMENT] = g_signal_new ("resend-new-segment", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, - G_STRUCT_OFFSET (GstVideoConnectorClass, resend_new_segment), nullptr, nullptr, + G_STRUCT_OFFSET (GstVideoConnectorClass, resend_new_segment), NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); gst_video_connector_signals[SIGNAL_CONNECTION_FAILED] = g_signal_new ("connection-failed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, - 0, nullptr, nullptr, + 0, NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } @@ -159,7 +159,7 @@ gst_video_connector_init (GstVideoConnector *element, element->relinked = FALSE; element->failedSignalEmited = FALSE; gst_segment_init (&element->segment, GST_FORMAT_TIME); - element->latest_buffer = nullptr; + element->latest_buffer = NULL; } static void @@ -167,9 +167,9 @@ gst_video_connector_reset (GstVideoConnector * element) { element->relinked = FALSE; element->failedSignalEmited = FALSE; - if (element->latest_buffer != nullptr) { + if (element->latest_buffer != NULL) { gst_buffer_unref (element->latest_buffer); - element->latest_buffer = nullptr; + element->latest_buffer = NULL; } gst_segment_init (&element->segment, GST_FORMAT_UNDEFINED); } @@ -196,7 +196,7 @@ gst_video_connector_buffer_alloc (GstPad * pad, guint64 offset, guint size, if (!buf) return GST_FLOW_ERROR; - *buf = nullptr; + *buf = NULL; gboolean isFailed = FALSE; while (1) { @@ -265,7 +265,7 @@ gst_video_connector_setcaps (GstPad *pad, GstCaps *caps) /* forward-negotiate */ gboolean res = gst_pad_set_caps(element->srcpad, caps); - gchar * debugmsg = nullptr; + gchar * debugmsg = NULL; GST_DEBUG_OBJECT(element, "gst_video_connector_setcaps %s %i", debugmsg = gst_caps_to_string(caps), res); if (debugmsg) g_free(debugmsg); @@ -407,7 +407,7 @@ gst_video_connector_chain (GstPad * pad, GstBuffer * buf) if (element->latest_buffer) { gst_buffer_unref (element->latest_buffer); - element->latest_buffer = nullptr; + element->latest_buffer = NULL; } element->latest_buffer = gst_buffer_ref(buf); diff --git a/src/gsttools/qgstreamerplayersession.cpp b/src/gsttools/qgstreamerplayersession.cpp index f7f3b7ca1..adf11b022 100644 --- a/src/gsttools/qgstreamerplayersession.cpp +++ b/src/gsttools/qgstreamerplayersession.cpp @@ -162,7 +162,15 @@ void QGstreamerPlayerSession::initPlaybin() } #if GST_CHECK_VERSION(1,0,0) - m_videoIdentity = gst_element_factory_make("identity", nullptr); // floating ref + static const auto convDesc = qEnvironmentVariable("QT_GSTREAMER_PLAYBIN_CONVERT"); + GError *err = nullptr; + auto convPipeline = !convDesc.isEmpty() ? convDesc.toLatin1().constData() : "identity"; + auto convElement = gst_parse_launch(convPipeline, &err); + if (err) { + qWarning() << "Error:" << convDesc << ":" << QLatin1String(err->message); + g_clear_error(&err); + } + m_videoIdentity = convElement; #else m_videoIdentity = GST_ELEMENT(g_object_new(gst_video_connector_get_type(), 0)); // floating ref g_signal_connect(G_OBJECT(m_videoIdentity), "connection-failed", G_CALLBACK(insertColorSpaceElement), (gpointer)this); diff --git a/src/multimedia/configure.json b/src/multimedia/configure.json index e9480dfc5..7f9b5d064 100644 --- a/src/multimedia/configure.json +++ b/src/multimedia/configure.json @@ -54,7 +54,7 @@ "test": "gstreamer", "sources": [ { "type": "pkgConfig", - "args": "gstreamer-1.0 gstreamer-base-1.0 gstreamer-audio-1.0 gstreamer-video-1.0 gstreamer-pbutils-1.0" }, + "args": "gstreamer-1.0 gstreamer-base-1.0 gstreamer-audio-1.0 gstreamer-video-1.0 gstreamer-pbutils-1.0 gstreamer-allocators-1.0" }, { "libs": "-lgstreamer-1.0 -lgstbase-1.0 -lgstaudio-1.0 -lgstvideo-1.0 -lgstpbutils-1.0 -lglib-2.0 -lgobject-2.0", "condition": "config.win32 || config.macos" }, { "libs": "", "condition": "config.android && input.gstreamer != ''" } @@ -109,18 +109,6 @@ { "type": "pkgConfig", "args": "gstreamer-gl-1.0" } ] }, - "gstreamer_imxcommon": { - "label": "GStreamer i.MX common", - "export": "gstreamer_imxcommon", - "test": { - "include": "gst/allocators/imx/phys_mem_meta.h" - }, - "use": "gstreamer_1_0", - "sources": [ - { "type": "pkgConfig", - "args": "gstimxcommon" } - ] - }, "libresourceqt5": { "label": "libresourceqt5", "test": "resourcepolicy", @@ -260,11 +248,6 @@ "condition": "features.opengl && features.gstreamer_1_0 && libs.gstreamer_gl_1_0", "output": [ "privateFeature" ] }, - "gstreamer_imxcommon": { - "label": "GStreamer i.MX common", - "condition": "(features.gstreamer_1_0 && libs.gstreamer_imxcommon)", - "output": [ "privateFeature" ] - }, "gpu_vivante": { "label": "Vivante GPU", "condition": "features.gui && features.opengles2 && tests.gpu_vivante", diff --git a/src/multimedia/multimedia.pro b/src/multimedia/multimedia.pro index 6efee8040..b783efbe0 100644 --- a/src/multimedia/multimedia.pro +++ b/src/multimedia/multimedia.pro @@ -25,7 +25,6 @@ PRIVATE_HEADERS += \ qmediaresourcepolicy_p.h \ qmediaresourceset_p.h \ qmediastoragelocation_p.h \ - qmediaopenglhelper_p.h \ qmultimediautils_p.h PUBLIC_HEADERS += \ diff --git a/src/multimedia/qmediaopenglhelper_p.h b/src/multimedia/qmediaopenglhelper_p.h deleted file mode 100644 index 0a65b9f53..000000000 --- a/src/multimedia/qmediaopenglhelper_p.h +++ /dev/null @@ -1,115 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QMEDIAOPENGLHELPER_P_H -#define QMEDIAOPENGLHELPER_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtGui/QOpenGLContext> - -#if defined(Q_OS_WIN) && !defined(Q_OS_WINRT) && (defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)) -#include <EGL/egl.h> -#endif - -QT_BEGIN_NAMESPACE - -class QMediaOpenGLHelper -{ -public: - static bool isANGLE(); -}; - -inline bool QMediaOpenGLHelper::isANGLE() -{ -#ifdef Q_OS_WINRT - return true; -#else - bool isANGLE = false; - -# if defined(Q_OS_WIN) && (defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC)) - if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES) { - // Although unlikely, technically LibGLES could mean a non-ANGLE EGL/GLES2 implementation too. - // Verify that it is indeed ANGLE. -# ifdef QT_OPENGL_ES_2_ANGLE_STATIC - // ANGLE linked-in statically. - isANGLE = true; -# else - // Qt configured with either -opengl es2 or -opengl desktop. -# ifdef QT_DEBUG - HMODULE eglHandle = LoadLibraryW(L"libEGLd.dll"); -# else - HMODULE eglHandle = LoadLibraryW(L"libEGL.dll"); -# endif // QT_DEBUG - if (eglHandle) { - typedef EGLDisplay (EGLAPIENTRYP EglGetDisplay)(EGLNativeDisplayType display_id); - typedef EGLBoolean (EGLAPIENTRYP EglInitialize)(EGLDisplay dpy, EGLint *major, EGLint *minor); - typedef const char * (EGLAPIENTRYP EglQueryString)(EGLDisplay dpy, EGLint name); - EglGetDisplay eglGetDisplay = (EglGetDisplay) GetProcAddress(eglHandle, "eglGetDisplay"); - EglInitialize eglInitialize = (EglInitialize) GetProcAddress(eglHandle, "eglInitialize"); - EglQueryString eglQueryString = (EglQueryString) GetProcAddress(eglHandle, "eglQueryString"); - if (eglGetDisplay && eglInitialize && eglQueryString) { - // EGL may not be initialized at this stage. - EGLDisplay dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY); - eglInitialize(dpy, 0, 0); - const char *vendorStr = eglQueryString(dpy, EGL_VERSION); - isANGLE = vendorStr && strstr(vendorStr, "ANGLE"); - } - } -# endif // QT_OPENGL_ES_2_ANGLE_STATIC - - } -# endif // Q_OS_WIN && (QT_OPENGL_ES_2 || QT_OPENGL_DYNAMIC) - - return isANGLE; -#endif // Q_OS_WINRT -} - -QT_END_NAMESPACE - -#endif diff --git a/src/multimedia/video/qvideooutputorientationhandler.cpp b/src/multimedia/video/qvideooutputorientationhandler.cpp index dac6eb0ba..e21efb37d 100644 --- a/src/multimedia/video/qvideooutputorientationhandler.cpp +++ b/src/multimedia/video/qvideooutputorientationhandler.cpp @@ -50,10 +50,6 @@ QVideoOutputOrientationHandler::QVideoOutputOrientationHandler(QObject *parent) { QScreen *screen = QGuiApplication::primaryScreen(); - // we want to be informed about all orientation changes - screen->setOrientationUpdateMask(Qt::PortraitOrientation|Qt::LandscapeOrientation - |Qt::InvertedPortraitOrientation|Qt::InvertedLandscapeOrientation); - connect(screen, SIGNAL(orientationChanged(Qt::ScreenOrientation)), this, SLOT(screenOrientationChanged(Qt::ScreenOrientation))); diff --git a/src/multimediawidgets/qpaintervideosurface.cpp b/src/multimediawidgets/qpaintervideosurface.cpp index 5fe76d869..6ba7cff02 100644 --- a/src/multimediawidgets/qpaintervideosurface.cpp +++ b/src/multimediawidgets/qpaintervideosurface.cpp @@ -44,7 +44,6 @@ #include <qpainter.h> #include <qvariant.h> #include <qvideosurfaceformat.h> -#include <private/qmediaopenglhelper_p.h> #if QT_CONFIG(opengl) #include <QOpenGLContext> @@ -278,9 +277,8 @@ protected: void initYv12TextureInfo(const QSize &size); bool needsSwizzling(const QVideoSurfaceFormat &format) const { - return !QMediaOpenGLHelper::isANGLE() - && (format.pixelFormat() == QVideoFrame::Format_RGB32 - || format.pixelFormat() == QVideoFrame::Format_ARGB32); + return format.pixelFormat() == QVideoFrame::Format_RGB32 + || format.pixelFormat() == QVideoFrame::Format_ARGB32; } QList<QVideoFrame::PixelFormat> m_imagePixelFormats; @@ -944,16 +942,17 @@ QAbstractVideoSurface::Error QVideoSurfaceArbFpPainter::paint( glActiveTexture(GL_TEXTURE0); } - glVertexPointer(2, GL_FLOAT, 0, v_array); - glTexCoordPointer(2, GL_FLOAT, 0, tx_array); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, v_array); + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, tx_array); - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); + glEnableVertexAttribArray(0); + glEnableVertexAttribArray(1); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_VERTEX_ARRAY); + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); + glDisable(GL_FRAGMENT_PROGRAM_ARB); painter->endNativePainting(); diff --git a/src/plugins/alsa/qalsaaudiodeviceinfo.h b/src/plugins/alsa/qalsaaudiodeviceinfo.h index 65675df54..cdf08bfab 100644 --- a/src/plugins/alsa/qalsaaudiodeviceinfo.h +++ b/src/plugins/alsa/qalsaaudiodeviceinfo.h @@ -79,15 +79,15 @@ public: bool testSettings(const QAudioFormat& format) const; void updateLists(); - QAudioFormat preferredFormat() const; - bool isFormatSupported(const QAudioFormat& format) const; - QString deviceName() const; - QStringList supportedCodecs(); - QList<int> supportedSampleRates(); - QList<int> supportedChannelCounts(); - QList<int> supportedSampleSizes(); - QList<QAudioFormat::Endian> supportedByteOrders(); - QList<QAudioFormat::SampleType> supportedSampleTypes(); + QAudioFormat preferredFormat() const override; + bool isFormatSupported(const QAudioFormat& format) const override; + QString deviceName() const override; + QStringList supportedCodecs() override; + QList<int> supportedSampleRates() override; + QList<int> supportedChannelCounts() override; + QList<int> supportedSampleSizes() override; + QList<QAudioFormat::Endian> supportedByteOrders() override; + QList<QAudioFormat::SampleType> supportedSampleTypes() override; static QByteArray defaultDevice(QAudio::Mode mode); static QList<QByteArray> availableDevices(QAudio::Mode); static QString deviceFromCardName(const QString &card); diff --git a/src/plugins/alsa/qalsaaudioinput.h b/src/plugins/alsa/qalsaaudioinput.h index fa9c954d7..62e1be039 100644 --- a/src/plugins/alsa/qalsaaudioinput.h +++ b/src/plugins/alsa/qalsaaudioinput.h @@ -103,26 +103,26 @@ public: qint64 read(char* data, qint64 len); - void start(QIODevice* device); - QIODevice* start(); - void stop(); - void reset(); - void suspend(); - void resume(); - int bytesReady() const; - int periodSize() const; - void setBufferSize(int value); - int bufferSize() const; - void setNotifyInterval(int milliSeconds); - int notifyInterval() const; - qint64 processedUSecs() const; - qint64 elapsedUSecs() const; - QAudio::Error error() const; - QAudio::State state() const; - void setFormat(const QAudioFormat& fmt); - QAudioFormat format() const; - void setVolume(qreal); - qreal volume() const; + void start(QIODevice* device) override; + QIODevice* start() override; + void stop() override; + void reset() override; + void suspend() override; + void resume() override; + int bytesReady() const override; + int periodSize() const override; + void setBufferSize(int value) override; + int bufferSize() const override; + void setNotifyInterval(int milliSeconds) override; + int notifyInterval() const override; + qint64 processedUSecs() const override; + qint64 elapsedUSecs() const override; + QAudio::Error error() const override; + QAudio::State state() const override; + void setFormat(const QAudioFormat& fmt) override; + QAudioFormat format() const override; + void setVolume(qreal) override; + qreal volume() const override; bool resuming; snd_pcm_t* handle; qint64 totalTimeValue; @@ -171,8 +171,8 @@ public: AlsaInputPrivate(QAlsaAudioInput* audio); ~AlsaInputPrivate(); - qint64 readData( char* data, qint64 len); - qint64 writeData(const char* data, qint64 len); + qint64 readData( char* data, qint64 len) override; + qint64 writeData(const char* data, qint64 len) override; void trigger(); private: diff --git a/src/plugins/alsa/qalsaaudiooutput.h b/src/plugins/alsa/qalsaaudiooutput.h index 8002322cb..72b9c2e4c 100644 --- a/src/plugins/alsa/qalsaaudiooutput.h +++ b/src/plugins/alsa/qalsaaudiooutput.h @@ -77,26 +77,26 @@ public: qint64 write( const char *data, qint64 len ); - void start(QIODevice* device); - QIODevice* start(); - void stop(); - void reset(); - void suspend(); - void resume(); - int bytesFree() const; - int periodSize() const; - void setBufferSize(int value); - int bufferSize() const; - void setNotifyInterval(int milliSeconds); - int notifyInterval() const; - qint64 processedUSecs() const; - qint64 elapsedUSecs() const; - QAudio::Error error() const; - QAudio::State state() const; - void setFormat(const QAudioFormat& fmt); - QAudioFormat format() const; - void setVolume(qreal); - qreal volume() const; + void start(QIODevice* device) override; + QIODevice* start() override; + void stop() override; + void reset() override; + void suspend() override; + void resume() override; + int bytesFree() const override; + int periodSize() const override; + void setBufferSize(int value) override; + int bufferSize() const override; + void setNotifyInterval(int milliSeconds) override; + int notifyInterval() const override; + qint64 processedUSecs() const override; + qint64 elapsedUSecs() const override; + QAudio::Error error() const override; + QAudio::State state() const override; + void setFormat(const QAudioFormat& fmt) override; + QAudioFormat format() const override; + void setVolume(qreal) override; + qreal volume() const override; QIODevice* audioSource; @@ -151,8 +151,8 @@ public: AlsaOutputPrivate(QAlsaAudioOutput* audio); ~AlsaOutputPrivate(); - qint64 readData( char* data, qint64 len); - qint64 writeData(const char* data, qint64 len); + qint64 readData( char* data, qint64 len) override; + qint64 writeData(const char* data, qint64 len) override; private: QAlsaAudioOutput *audioDevice; diff --git a/src/plugins/common/evr/evrd3dpresentengine.cpp b/src/plugins/common/evr/evrd3dpresentengine.cpp index d8e2da6d3..964504e48 100644 --- a/src/plugins/common/evr/evrd3dpresentengine.cpp +++ b/src/plugins/common/evr/evrd3dpresentengine.cpp @@ -46,187 +46,12 @@ #include <qvideoframe.h> #include <QDebug> #include <qthread.h> -#include <private/qmediaopenglhelper_p.h> #include <QOffscreenSurface> -#ifdef MAYBE_ANGLE -# include <qguiapplication.h> -# include <qpa/qplatformnativeinterface.h> -# include <qopenglfunctions.h> -# include <EGL/eglext.h> -#endif - static const int PRESENTER_BUFFER_COUNT = 3; QT_BEGIN_NAMESPACE -#ifdef MAYBE_ANGLE - -EGLWrapper::EGLWrapper() -{ -#ifndef QT_OPENGL_ES_2_ANGLE_STATIC - // Resolve the EGL functions we use. When configured for dynamic OpenGL, no - // component in Qt will link to libEGL.lib and libGLESv2.lib. We know - // however that libEGL is loaded for sure, since this is an ANGLE-only path. - -# ifdef QT_DEBUG - HMODULE eglHandle = GetModuleHandle(L"libEGLd.dll"); -# else - HMODULE eglHandle = GetModuleHandle(L"libEGL.dll"); -# endif - - if (!eglHandle) - qWarning("No EGL library loaded"); - - m_eglGetProcAddress = (EglGetProcAddress) GetProcAddress(eglHandle, "eglGetProcAddress"); - m_eglCreatePbufferSurface = (EglCreatePbufferSurface) GetProcAddress(eglHandle, "eglCreatePbufferSurface"); - m_eglDestroySurface = (EglDestroySurface) GetProcAddress(eglHandle, "eglDestroySurface"); - m_eglBindTexImage = (EglBindTexImage) GetProcAddress(eglHandle, "eglBindTexImage"); - m_eglReleaseTexImage = (EglReleaseTexImage) GetProcAddress(eglHandle, "eglReleaseTexImage"); -#else - // Static ANGLE-only build. There is no libEGL.dll in use. - - m_eglGetProcAddress = ::eglGetProcAddress; - m_eglCreatePbufferSurface = ::eglCreatePbufferSurface; - m_eglDestroySurface = ::eglDestroySurface; - m_eglBindTexImage = ::eglBindTexImage; - m_eglReleaseTexImage = ::eglReleaseTexImage; -#endif -} - -__eglMustCastToProperFunctionPointerType EGLWrapper::getProcAddress(const char *procname) -{ - Q_ASSERT(m_eglGetProcAddress); - return m_eglGetProcAddress(procname); -} - -EGLSurface EGLWrapper::createPbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) -{ - Q_ASSERT(m_eglCreatePbufferSurface); - return m_eglCreatePbufferSurface(dpy, config, attrib_list); -} - -EGLBoolean EGLWrapper::destroySurface(EGLDisplay dpy, EGLSurface surface) -{ - Q_ASSERT(m_eglDestroySurface); - return m_eglDestroySurface(dpy, surface); -} - -EGLBoolean EGLWrapper::bindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) -{ - Q_ASSERT(m_eglBindTexImage); - return m_eglBindTexImage(dpy, surface, buffer); -} - -EGLBoolean EGLWrapper::releaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) -{ - Q_ASSERT(m_eglReleaseTexImage); - return m_eglReleaseTexImage(dpy, surface, buffer); -} - - -class OpenGLResources : public QObject -{ -public: - OpenGLResources() - : m_egl(new EGLWrapper) - , m_eglDisplay(nullptr) - , m_eglSurface(nullptr) - , m_glTexture(0) - , m_glContext(QOpenGLContext::currentContext()) - { - Q_ASSERT(m_glContext); - } - - unsigned int glTexture() const - { - return m_glTexture; - } - - void createTexture(const QVideoSurfaceFormat &format, IDirect3DDevice9Ex *device, - IDirect3DTexture9 **texture) - { - if (!m_glContext) - return; - - m_glContext->functions()->glGenTextures(1, &m_glTexture); - QPlatformNativeInterface *nativeInterface = QGuiApplication::platformNativeInterface(); - m_eglDisplay = static_cast<EGLDisplay*>( - nativeInterface->nativeResourceForContext("eglDisplay", m_glContext)); - EGLConfig *eglConfig = static_cast<EGLConfig*>( - nativeInterface->nativeResourceForContext("eglConfig", m_glContext)); - - const bool hasAlpha = m_glContext->format().hasAlpha(); - - EGLint attribs[] = { - EGL_WIDTH, format.frameWidth(), - EGL_HEIGHT, format.frameHeight(), - EGL_TEXTURE_FORMAT, (hasAlpha ? EGL_TEXTURE_RGBA : EGL_TEXTURE_RGB), - EGL_TEXTURE_TARGET, EGL_TEXTURE_2D, - EGL_NONE - }; - - m_eglSurface = m_egl->createPbufferSurface(m_eglDisplay, eglConfig, attribs); - - HANDLE share_handle = 0; - PFNEGLQUERYSURFACEPOINTERANGLEPROC eglQuerySurfacePointerANGLE = - reinterpret_cast<PFNEGLQUERYSURFACEPOINTERANGLEPROC>( - m_egl->getProcAddress("eglQuerySurfacePointerANGLE")); - Q_ASSERT(eglQuerySurfacePointerANGLE); - eglQuerySurfacePointerANGLE( - m_eglDisplay, - m_eglSurface, - EGL_D3D_TEXTURE_2D_SHARE_HANDLE_ANGLE, &share_handle); - - device->CreateTexture(format.frameWidth(), format.frameHeight(), 1, - D3DUSAGE_RENDERTARGET, - (hasAlpha ? D3DFMT_A8R8G8B8 : D3DFMT_X8R8G8B8), - D3DPOOL_DEFAULT, texture, &share_handle); - - m_glContext->functions()->glBindTexture(GL_TEXTURE_2D, m_glTexture); - m_egl->bindTexImage(m_eglDisplay, m_eglSurface, EGL_BACK_BUFFER); - } - - void release() - { - if (thread() == QThread::currentThread()) - delete this; - else - deleteLater(); - } - -private: - EGLWrapper *m_egl; - EGLDisplay *m_eglDisplay; - EGLSurface m_eglSurface; - unsigned int m_glTexture; - QOpenGLContext *m_glContext; - - ~OpenGLResources() override - { - QScopedPointer<QOffscreenSurface> surface; - if (m_glContext != QOpenGLContext::currentContext()) { - surface.reset(new QOffscreenSurface); - surface->create(); - m_glContext->makeCurrent(surface.data()); - } - - if (m_eglSurface && m_egl) { - m_egl->releaseTexImage(m_eglDisplay, m_eglSurface, EGL_BACK_BUFFER); - m_egl->destroySurface(m_eglDisplay, m_eglSurface); - } - if (m_glTexture) - m_glContext->functions()->glDeleteTextures(1, &m_glTexture); - - delete m_egl; - if (surface) - m_glContext->doneCurrent(); - } -}; - -#endif // MAYBE_ANGLE - - class IMFSampleVideoBuffer: public QAbstractVideoBuffer { public: @@ -311,11 +136,6 @@ void IMFSampleVideoBuffer::unmap() QVariant IMFSampleVideoBuffer::handle() const { -#ifdef MAYBE_ANGLE - if (handleType() == GLTextureHandle && !m_textureId) - m_textureId = m_engine->updateTexture(m_surface); -#endif - return m_textureId; } @@ -326,10 +146,6 @@ D3DPresentEngine::D3DPresentEngine() , m_device(0) , m_deviceManager(0) , m_useTextureRendering(false) -#ifdef MAYBE_ANGLE - , m_glResources(0) - , m_texture(0) -#endif { ZeroMemory(&m_displayMode, sizeof(m_displayMode)); @@ -441,15 +257,6 @@ bool D3DPresentEngine::isValid() const void D3DPresentEngine::releaseResources() { m_surfaceFormat = QVideoSurfaceFormat(); - -#ifdef MAYBE_ANGLE - qt_evr_safe_release(&m_texture); - - if (m_glResources) { - m_glResources->release(); // deleted in GL thread - m_glResources = NULL; - } -#endif } HRESULT D3DPresentEngine::getService(REFGUID, REFIID riid, void** ppv) @@ -507,11 +314,7 @@ HRESULT D3DPresentEngine::checkFormat(D3DFORMAT format) bool D3DPresentEngine::supportsTextureRendering() const { -#ifdef MAYBE_ANGLE - return QMediaOpenGLHelper::isANGLE(); -#else return false; -#endif } void D3DPresentEngine::setHint(Hint hint, bool enable) @@ -607,46 +410,4 @@ QVideoFrame D3DPresentEngine::makeVideoFrame(IMFSample *sample) return frame; } -#ifdef MAYBE_ANGLE - -unsigned int D3DPresentEngine::updateTexture(IDirect3DSurface9 *src) -{ - if (!m_texture) { - if (m_glResources) - m_glResources->release(); - - m_glResources = new OpenGLResources; - m_glResources->createTexture(m_surfaceFormat, m_device, &m_texture); - } - - IDirect3DSurface9 *dest = NULL; - - // Copy the sample surface to the shared D3D/EGL surface - HRESULT hr = m_texture ? m_texture->GetSurfaceLevel(0, &dest) : E_FAIL; - if (FAILED(hr)) - goto done; - - hr = m_device->StretchRect(src, NULL, dest, NULL, D3DTEXF_NONE); - if (FAILED(hr)) { - qWarning("Failed to copy D3D surface"); - } else { - // Shared surfaces are not synchronized, there's no guarantee that - // StretchRect is complete when the texture is later rendered by Qt. - // To make sure the next rendered frame is up to date, flush the command pipeline - // using an event query. - IDirect3DQuery9 *eventQuery = NULL; - m_device->CreateQuery(D3DQUERYTYPE_EVENT, &eventQuery); - eventQuery->Issue(D3DISSUE_END); - while (eventQuery->GetData(NULL, 0, D3DGETDATA_FLUSH) == S_FALSE); - eventQuery->Release(); - } - -done: - qt_evr_safe_release(&dest); - - return (SUCCEEDED(hr) && m_glResources) ? m_glResources->glTexture() : 0; -} - -#endif // MAYBE_ANGLE - QT_END_NAMESPACE diff --git a/src/plugins/common/evr/evrd3dpresentengine.h b/src/plugins/common/evr/evrd3dpresentengine.h index 8e2a444f3..eb2def7b2 100644 --- a/src/plugins/common/evr/evrd3dpresentengine.h +++ b/src/plugins/common/evr/evrd3dpresentengine.h @@ -45,11 +45,6 @@ #include <d3d9.h> -#if defined(QT_OPENGL_ES_2) || defined(QT_OPENGL_DYNAMIC) -# include <EGL/egl.h> -# define MAYBE_ANGLE -#endif - struct IDirect3D9Ex; struct IDirect3DDevice9Ex; struct IDirect3DDeviceManager9; diff --git a/src/plugins/directshow/player/directshowmetadatacontrol.cpp b/src/plugins/directshow/player/directshowmetadatacontrol.cpp index d9864870a..61138951c 100644 --- a/src/plugins/directshow/player/directshowmetadatacontrol.cpp +++ b/src/plugins/directshow/player/directshowmetadatacontrol.cpp @@ -323,7 +323,7 @@ static QVariant getValue(IWMHeaderInfo *header, const wchar_t *key) &streamNumber, key, &type, - reinterpret_cast<BYTE *>(const_cast<ushort *>(string.utf16())), + reinterpret_cast<BYTE *>(string.data()), &size) == S_OK) { return string; } diff --git a/src/plugins/gstreamer/mediacapture/qgstreamerrecordercontrol.cpp b/src/plugins/gstreamer/mediacapture/qgstreamerrecordercontrol.cpp index ba26d8df8..640f659b6 100644 --- a/src/plugins/gstreamer/mediacapture/qgstreamerrecordercontrol.cpp +++ b/src/plugins/gstreamer/mediacapture/qgstreamerrecordercontrol.cpp @@ -43,6 +43,7 @@ #include "qgstreamermediacontainercontrol.h" #include <QtCore/QDebug> #include <QtGui/qdesktopservices.h> +#include <QStandardPaths> QGstreamerRecorderControl::QGstreamerRecorderControl(QGstreamerCaptureSession *session) :QMediaRecorderControl(session), diff --git a/src/plugins/m3u/qm3uhandler.cpp b/src/plugins/m3u/qm3uhandler.cpp index df1f3fd7e..b88e3e292 100644 --- a/src/plugins/m3u/qm3uhandler.cpp +++ b/src/plugins/m3u/qm3uhandler.cpp @@ -77,14 +77,14 @@ public: delete m_textStream; } - virtual bool atEnd() const + bool atEnd() const override { //we can't just use m_textStream->atEnd(), //for files with empty lines/comments at end return nextResource.isNull(); } - virtual QMediaContent readItem() + QMediaContent readItem() override { QMediaContent item; if (!nextResource.isNull()) @@ -135,7 +135,7 @@ public: return item; } - virtual void close() + void close() override { } @@ -160,13 +160,13 @@ public: delete m_textStream; } - virtual bool writeItem(const QMediaContent& item) + bool writeItem(const QMediaContent& item) override { *m_textStream << item.request().url().toString() << Qt::endl; return true; } - virtual void close() + void close() override { } diff --git a/src/plugins/m3u/qm3uhandler.h b/src/plugins/m3u/qm3uhandler.h index 509ac11d5..1bc0684d3 100644 --- a/src/plugins/m3u/qm3uhandler.h +++ b/src/plugins/m3u/qm3uhandler.h @@ -54,15 +54,15 @@ public: explicit QM3uPlaylistPlugin(QObject *parent = 0); virtual ~QM3uPlaylistPlugin(); - virtual bool canRead(QIODevice *device, const QByteArray &format = QByteArray() ) const; - virtual bool canRead(const QUrl& location, const QByteArray &format = QByteArray()) const; + bool canRead(QIODevice *device, const QByteArray &format = QByteArray()) const override; + bool canRead(const QUrl& location, const QByteArray &format = QByteArray()) const override; - virtual bool canWrite(QIODevice *device, const QByteArray &format) const; + bool canWrite(QIODevice *device, const QByteArray &format) const override; - virtual QMediaPlaylistReader *createReader(QIODevice *device, const QByteArray &format = QByteArray()); - virtual QMediaPlaylistReader *createReader(const QUrl& location, const QByteArray &format = QByteArray()); + QMediaPlaylistReader *createReader(QIODevice *device, const QByteArray &format = QByteArray()) override; + QMediaPlaylistReader *createReader(const QUrl& location, const QByteArray &format = QByteArray()) override; - virtual QMediaPlaylistWriter *createWriter(QIODevice *device, const QByteArray &format); + QMediaPlaylistWriter *createWriter(QIODevice *device, const QByteArray &format) override; }; #endif // QM3UHANDLER_H diff --git a/src/plugins/opensles/qopenslesaudioinput.h b/src/plugins/opensles/qopenslesaudioinput.h index 35cc37959..730c58bd6 100644 --- a/src/plugins/opensles/qopenslesaudioinput.h +++ b/src/plugins/opensles/qopenslesaudioinput.h @@ -41,7 +41,7 @@ #define QOPENSLESAUDIOINPUT_H #include <qaudiosystem.h> -#include <QTime> +#include <QElapsedTimer> #include <SLES/OpenSLES.h> #ifdef ANDROID @@ -118,7 +118,7 @@ private: QAudioFormat m_format; QAudio::Error m_errorState; QAudio::State m_deviceState; - QTime m_clockStamp; + QElapsedTimer m_clockStamp; qint64 m_lastNotifyTime; qreal m_volume; int m_bufferSize; diff --git a/src/plugins/opensles/qopenslesaudiooutput.h b/src/plugins/opensles/qopenslesaudiooutput.h index b480f00e6..80959df30 100644 --- a/src/plugins/opensles/qopenslesaudiooutput.h +++ b/src/plugins/opensles/qopenslesaudiooutput.h @@ -44,7 +44,7 @@ #include <SLES/OpenSLES.h> #include <qbytearray.h> #include <qmap.h> -#include <QTime> +#include <QElapsedTimer> #include <QIODevice> QT_BEGIN_NAMESPACE @@ -126,7 +126,7 @@ private: bool m_startRequiresInit; qint32 m_streamType; - QTime m_clockStamp; + QElapsedTimer m_clockStamp; QAudioFormat m_format; QString m_category; static QMap<QString, qint32> m_categories; diff --git a/src/plugins/pulseaudio/qaudiodeviceinfo_pulse.h b/src/plugins/pulseaudio/qaudiodeviceinfo_pulse.h index 64537229f..1cec772c0 100644 --- a/src/plugins/pulseaudio/qaudiodeviceinfo_pulse.h +++ b/src/plugins/pulseaudio/qaudiodeviceinfo_pulse.h @@ -69,15 +69,15 @@ public: QPulseAudioDeviceInfo(const QByteArray &device, QAudio::Mode mode); ~QPulseAudioDeviceInfo() {} - QAudioFormat preferredFormat() const; - bool isFormatSupported(const QAudioFormat &format) const; - QString deviceName() const; - QStringList supportedCodecs(); - QList<int> supportedSampleRates(); - QList<int> supportedChannelCounts(); - QList<int> supportedSampleSizes(); - QList<QAudioFormat::Endian> supportedByteOrders(); - QList<QAudioFormat::SampleType> supportedSampleTypes(); + QAudioFormat preferredFormat() const override; + bool isFormatSupported(const QAudioFormat &format) const override; + QString deviceName() const override; + QStringList supportedCodecs() override; + QList<int> supportedSampleRates() override; + QList<int> supportedChannelCounts() override; + QList<int> supportedSampleSizes() override; + QList<QAudioFormat::Endian> supportedByteOrders() override; + QList<QAudioFormat::SampleType> supportedSampleTypes() override; private: QByteArray m_device; diff --git a/src/plugins/pulseaudio/qaudioinput_pulse.h b/src/plugins/pulseaudio/qaudioinput_pulse.h index 3a6cf03c4..dce212a25 100644 --- a/src/plugins/pulseaudio/qaudioinput_pulse.h +++ b/src/plugins/pulseaudio/qaudioinput_pulse.h @@ -78,27 +78,27 @@ public: qint64 read(char *data, qint64 len); - void start(QIODevice *device); - QIODevice *start(); - void stop(); - void reset(); - void suspend(); - void resume(); - int bytesReady() const; - int periodSize() const; - void setBufferSize(int value); - int bufferSize() const; - void setNotifyInterval(int milliSeconds); - int notifyInterval() const; - qint64 processedUSecs() const; - qint64 elapsedUSecs() const; - QAudio::Error error() const; - QAudio::State state() const; - void setFormat(const QAudioFormat &format); - QAudioFormat format() const; - - void setVolume(qreal volume); - qreal volume() const; + void start(QIODevice *device) override; + QIODevice *start() override; + void stop() override; + void reset() override; + void suspend() override; + void resume() override; + int bytesReady() const override; + int periodSize() const override; + void setBufferSize(int value) override; + int bufferSize() const override; + void setNotifyInterval(int milliSeconds) override; + int notifyInterval() const override; + qint64 processedUSecs() const override; + qint64 elapsedUSecs() const override; + QAudio::Error error() const override; + QAudio::State state() const override; + void setFormat(const QAudioFormat &format) override; + QAudioFormat format() const override; + + void setVolume(qreal volume) override; + qreal volume() const override; qint64 m_totalTimeValue; QIODevice *m_audioSource; @@ -147,8 +147,8 @@ public: PulseInputPrivate(QPulseAudioInput *audio); ~PulseInputPrivate() {}; - qint64 readData(char *data, qint64 len); - qint64 writeData(const char *data, qint64 len); + qint64 readData(char *data, qint64 len) override; + qint64 writeData(const char *data, qint64 len) override; void trigger(); diff --git a/src/plugins/pulseaudio/qaudiooutput_pulse.h b/src/plugins/pulseaudio/qaudiooutput_pulse.h index 40d052681..e11f2ab2f 100644 --- a/src/plugins/pulseaudio/qaudiooutput_pulse.h +++ b/src/plugins/pulseaudio/qaudiooutput_pulse.h @@ -75,30 +75,30 @@ public: QPulseAudioOutput(const QByteArray &device); ~QPulseAudioOutput(); - void start(QIODevice *device); - QIODevice *start(); - void stop(); - void reset(); - void suspend(); - void resume(); - int bytesFree() const; - int periodSize() const; - void setBufferSize(int value); - int bufferSize() const; - void setNotifyInterval(int milliSeconds); - int notifyInterval() const; - qint64 processedUSecs() const; - qint64 elapsedUSecs() const; - QAudio::Error error() const; - QAudio::State state() const; - void setFormat(const QAudioFormat &format); - QAudioFormat format() const; - - void setVolume(qreal volume); - qreal volume() const; - - void setCategory(const QString &category); - QString category() const; + void start(QIODevice *device) override; + QIODevice *start() override; + void stop() override; + void reset() override; + void suspend() override; + void resume() override; + int bytesFree() const override; + int periodSize() const override; + void setBufferSize(int value) override; + int bufferSize() const override; + void setNotifyInterval(int milliSeconds) override; + int notifyInterval() const override; + qint64 processedUSecs() const override; + qint64 elapsedUSecs() const override; + QAudio::Error error() const override; + QAudio::State state() const override; + void setFormat(const QAudioFormat &format) override; + QAudioFormat format() const override; + + void setVolume(qreal volume) override; + qreal volume() const override; + + void setCategory(const QString &category) override; + QString category() const override; public: void streamUnderflowCallback(); @@ -154,8 +154,8 @@ public: virtual ~PulseOutputPrivate() {} protected: - qint64 readData(char *data, qint64 len); - qint64 writeData(const char *data, qint64 len); + qint64 readData(char *data, qint64 len) override; + qint64 writeData(const char *data, qint64 len) override; private: QPulseAudioOutput *m_audioDevice; diff --git a/src/plugins/pulseaudio/qpulseaudioplugin.h b/src/plugins/pulseaudio/qpulseaudioplugin.h index 120d57df5..7d27cad48 100644 --- a/src/plugins/pulseaudio/qpulseaudioplugin.h +++ b/src/plugins/pulseaudio/qpulseaudioplugin.h @@ -58,11 +58,11 @@ public: QPulseAudioPlugin(QObject *parent = 0); ~QPulseAudioPlugin() {} - QByteArray defaultDevice(QAudio::Mode mode) const; - QList<QByteArray> availableDevices(QAudio::Mode mode) const; - QAbstractAudioInput *createInput(const QByteArray &device); - QAbstractAudioOutput *createOutput(const QByteArray &device); - QAbstractAudioDeviceInfo *createDeviceInfo(const QByteArray &device, QAudio::Mode mode); + QByteArray defaultDevice(QAudio::Mode mode) const override; + QList<QByteArray> availableDevices(QAudio::Mode mode) const override; + QAbstractAudioInput *createInput(const QByteArray &device) override; + QAbstractAudioOutput *createOutput(const QByteArray &device) override; + QAbstractAudioDeviceInfo *createDeviceInfo(const QByteArray &device, QAudio::Mode mode) override; private: QPulseAudioEngine *m_pulseEngine; diff --git a/src/plugins/qnx-audio/audio/qnxaudioinput.h b/src/plugins/qnx-audio/audio/qnxaudioinput.h index c677b6c96..a08491321 100644 --- a/src/plugins/qnx-audio/audio/qnxaudioinput.h +++ b/src/plugins/qnx-audio/audio/qnxaudioinput.h @@ -44,7 +44,7 @@ #include <QSocketNotifier> #include <QIODevice> -#include <QTime> +#include <QElapsedTimer> #include <QTimer> #include <sys/asoundlib.h> @@ -93,8 +93,8 @@ private: void setError(QAudio::Error error); void setState(QAudio::State state); - QTime m_timeStamp; - QTime m_clockStamp; + QElapsedTimer m_timeStamp; + QElapsedTimer m_clockStamp; QAudioFormat m_format; QIODevice *m_audioSource; diff --git a/src/plugins/qnx-audio/audio/qnxaudiooutput.h b/src/plugins/qnx-audio/audio/qnxaudiooutput.h index 7a0979f77..bbbd40b17 100644 --- a/src/plugins/qnx-audio/audio/qnxaudiooutput.h +++ b/src/plugins/qnx-audio/audio/qnxaudiooutput.h @@ -42,7 +42,7 @@ #include "qaudiosystem.h" -#include <QTime> +#include <QElapsedTimer> #include <QTimer> #include <QIODevice> #include <QSocketNotifier> @@ -119,8 +119,8 @@ private: snd_pcm_t *m_pcmHandle; qint64 m_bytesWritten; - QTime m_startTimeStamp; - QTime m_intervalTimeStamp; + QElapsedTimer m_startTimeStamp; + QElapsedTimer m_intervalTimeStamp; qint64 m_intervalOffset; #if _NTO_VERSION >= 700 diff --git a/src/plugins/videonode/imx6/imx6.pro b/src/plugins/videonode/imx6/imx6.pro index 43e17e725..0e9ed8b73 100644 --- a/src/plugins/videonode/imx6/imx6.pro +++ b/src/plugins/videonode/imx6/imx6.pro @@ -1,12 +1,8 @@ TARGET = imx6vivantevideonode -QT += multimedia-private qtmultimediaquicktools-private +QT += multimedia-private qtmultimediaquicktools-private multimediagsttools-private -qtConfig(gstreamer_imxcommon) { - QT += multimediagsttools-private - QMAKE_USE += gstreamer_imxcommon - DEFINES += GST_USE_UNSTABLE_API -} +QMAKE_USE += gstreamer HEADERS += \ qsgvivantevideonode.h \ diff --git a/src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp b/src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp index e8371d766..e200e8d16 100644 --- a/src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp +++ b/src/plugins/videonode/imx6/qsgvivantevideomaterial.cpp @@ -50,10 +50,8 @@ #include <unistd.h> #include <QtMultimedia/private/qtmultimediaglobal_p.h> -#if QT_CONFIG(gstreamer_imxcommon) #include "private/qgstvideobuffer_p.h" -#include <gst/allocators/imx/phys_mem_meta.h> -#endif +#include <gst/allocators/gstphysmemory.h> //#define QT_VIVANTE_VIDEO_DEBUG @@ -225,11 +223,12 @@ GLuint QSGVivanteVideoMaterial::vivanteMapping(QVideoFrame vF) #endif GLuint physical = ~0U; -#if QT_CONFIG(gstreamer_imxcommon) +#if GST_CHECK_VERSION(1,14,0) auto buffer = reinterpret_cast<QGstVideoBuffer *>(vF.buffer()); - GstImxPhysMemMeta *meta = GST_IMX_PHYS_MEM_META_GET(buffer->buffer()); - if (meta && meta->phys_addr) - physical = meta->phys_addr; + auto mem = gst_buffer_peek_memory(buffer->buffer(), 0); + auto phys_addr = gst_is_phys_memory(mem) ? gst_phys_memory_get_phys_addr(mem) : 0; + if (phys_addr) + physical = phys_addr; #endif glBindTexture(GL_TEXTURE_2D, tmpTexId); glTexDirectVIVMap_LOCAL(GL_TEXTURE_2D, diff --git a/src/plugins/wasapi/qwasapiaudioinput.h b/src/plugins/wasapi/qwasapiaudioinput.h index babfb5b10..6e9775490 100644 --- a/src/plugins/wasapi/qwasapiaudioinput.h +++ b/src/plugins/wasapi/qwasapiaudioinput.h @@ -42,7 +42,7 @@ #include <QtCore/QLoggingCategory> #include <QtCore/QMutex> -#include <QtCore/QTime> +#include <QtCore/QElapsedTimer> #include <QtMultimedia/QAbstractAudioInput> #include <QtMultimedia/QAudio> @@ -104,7 +104,7 @@ private: QAudio::Error m_currentError; QAudioFormat m_currentFormat; qint64 m_bytesProcessed; - QTime m_openTime; + QElapsedTimer m_openTime; int m_openTimeOffset; int m_interval; bool m_pullMode; diff --git a/src/plugins/wasapi/qwasapiaudiooutput.h b/src/plugins/wasapi/qwasapiaudiooutput.h index 49219c5cc..e5d5bc5b1 100644 --- a/src/plugins/wasapi/qwasapiaudiooutput.h +++ b/src/plugins/wasapi/qwasapiaudiooutput.h @@ -42,7 +42,7 @@ #include <QtCore/QLoggingCategory> #include <QtCore/QMutex> -#include <QtCore/QTime> +#include <QtCore/QElapsedTimer> #include <QtMultimedia/QAbstractAudioOutput> #include <QtMultimedia/QAudio> @@ -105,7 +105,7 @@ private: QAudio::Error m_currentError; QAudioFormat m_currentFormat; qint64 m_bytesProcessed; - QTime m_openTime; + QElapsedTimer m_openTime; int m_openTimeOffset; int m_interval; bool m_pullMode; diff --git a/src/plugins/wmf/player/mfvideorenderercontrol.cpp b/src/plugins/wmf/player/mfvideorenderercontrol.cpp index 94d5f68be..137fc5fc5 100644 --- a/src/plugins/wmf/player/mfvideorenderercontrol.cpp +++ b/src/plugins/wmf/player/mfvideorenderercontrol.cpp @@ -51,7 +51,6 @@ #include <qtcore/qthread.h> #include "guiddef.h" #include <qtcore/qdebug.h> -#include <QtMultimedia/private/qmediaopenglhelper_p.h> //#define DEBUG_MEDIAFOUNDATION #define PAD_TO_DWORD(x) (((x) + 3) & ~3) diff --git a/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp b/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp index ca3a4b2ea..caa022c5c 100644 --- a/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp +++ b/src/qtmultimediaquicktools/qdeclarativevideooutput.cpp @@ -828,12 +828,12 @@ void QDeclarativeVideoOutput::releaseResources() m_backend->releaseResources(); } -void QDeclarativeVideoOutput::geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) +void QDeclarativeVideoOutput::geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) { Q_UNUSED(newGeometry); Q_UNUSED(oldGeometry); - QQuickItem::geometryChanged(newGeometry, oldGeometry); + QQuickItem::geometryChange(newGeometry, oldGeometry); // Explicitly listen to geometry changes here. This is needed since changing the position does // not trigger a call to updatePaintNode(). diff --git a/src/qtmultimediaquicktools/qdeclarativevideooutput_p.h b/src/qtmultimediaquicktools/qdeclarativevideooutput_p.h index a29e11ccf..a7ed5c36d 100644 --- a/src/qtmultimediaquicktools/qdeclarativevideooutput_p.h +++ b/src/qtmultimediaquicktools/qdeclarativevideooutput_p.h @@ -156,7 +156,7 @@ Q_SIGNALS: protected: QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) override; void itemChange(ItemChange change, const ItemChangeData &changeData) override; - void geometryChanged(const QRectF &newGeometry, const QRectF &oldGeometry) override; + void geometryChange(const QRectF &newGeometry, const QRectF &oldGeometry) override; void releaseResources() override; private Q_SLOTS: diff --git a/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp b/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp index 4fb62921e..5746a644a 100644 --- a/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp +++ b/src/qtmultimediaquicktools/qsgvideonode_rgb.cpp @@ -37,6 +37,7 @@ ** ****************************************************************************/ #include "qsgvideonode_rgb_p.h" +#include "qsgvideotexture_p.h" #include <QtQuick/qsgtexturematerial.h> #include <QtQuick/qsgmaterial.h> #include <QtCore/qmutex.h> @@ -128,6 +129,21 @@ protected: bool m_hasAlpha; }; +class QSGVideoMaterialRhiShader_RGB : public QSGMaterialRhiShader +{ +public: + QSGVideoMaterialRhiShader_RGB() + { + setShaderFileName(VertexStage, QStringLiteral(":/qtmultimediaquicktools/shaders_ng/rgba.vert.qsb")); + setShaderFileName(FragmentStage, QStringLiteral(":/qtmultimediaquicktools/shaders_ng/rgba.frag.qsb")); + } + + bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, + QSGMaterial *oldMaterial) override; + + void updateSampledImage(RenderState &state, int binding, QSGTexture **texture, + QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override; +}; class QSGVideoMaterial_RGB : public QSGMaterial { @@ -139,6 +155,7 @@ public: m_width(1.0) { setFlag(Blending, false); + setFlag(SupportsRhiShader, true); } ~QSGVideoMaterial_RGB() @@ -153,6 +170,9 @@ public: } QSGMaterialShader *createShader() const override { + if (flags().testFlag(RhiShaderWanted)) + return new QSGVideoMaterialRhiShader_RGB; + const bool hasAlpha = m_format.pixelFormat() == QVideoFrame::Format_ARGB32; return needsSwizzling() ? new QSGVideoMaterialShader_RGB_swizzle(hasAlpha) : new QSGVideoMaterialShader_RGB; @@ -245,6 +265,7 @@ public: GLuint m_textureId; qreal m_opacity; GLfloat m_width; + QScopedPointer<QSGVideoTexture> m_texture; private: bool needsSwizzling() const { @@ -253,6 +274,63 @@ private: } }; +bool QSGVideoMaterialRhiShader_RGB::updateUniformData(RenderState &state, QSGMaterial *newMaterial, + QSGMaterial *oldMaterial) +{ + Q_UNUSED(newMaterial); + Q_UNUSED(oldMaterial); + + bool changed = false; + QByteArray *buf = state.uniformData(); + + if (state.isMatrixDirty()) { + memcpy(buf->data(), state.combinedMatrix().constData(), 64); + changed = true; + } + + if (state.isOpacityDirty()) { + const float opacity = state.opacity(); + memcpy(buf->data() + 64, &opacity, 4); + changed = true; + } + + return changed; +} + +void QSGVideoMaterialRhiShader_RGB::updateSampledImage(RenderState &state, int binding, QSGTexture **texture, + QSGMaterial *newMaterial, QSGMaterial *oldMaterial) +{ + Q_UNUSED(oldMaterial); + + if (binding < 1) + return; + + auto m = static_cast<QSGVideoMaterial_RGB *>(newMaterial); + if (!m->m_texture) + m->m_texture.reset(new QSGVideoTexture); + + m->m_frameMutex.lock(); + auto frame = m->m_frame; + m->m_frameMutex.unlock(); + + if (frame.pixelFormat() == QVideoFrame::Format_RGB565) // Format_RGB565 requires GL_UNSIGNED_SHORT_5_6_5 + frame = frame.image().convertToFormat(QImage::Format_RGBA8888_Premultiplied); + + auto format = QRhiTexture::RGBA8; + if (frame.pixelFormat() == QVideoFrame::Format_RGB32 + || frame.pixelFormat() == QVideoFrame::Format_ARGB32) + { + format = QRhiTexture::BGRA8; + } + + if (frame.isValid() && frame.map(QAbstractVideoBuffer::ReadOnly)) { + m->m_texture->setData(format, frame.size(), frame.bits(), frame.bytesPerLine() * frame.height()); + frame.unmap(); + } + + m->m_texture->commitTextureOperations(state.rhi(), state.resourceUpdateBatch()); + *texture = m->m_texture.data(); +} QSGVideoNode_RGB::QSGVideoNode_RGB(const QVideoSurfaceFormat &format) : m_format(format) diff --git a/src/qtmultimediaquicktools/qsgvideonode_texture.cpp b/src/qtmultimediaquicktools/qsgvideonode_texture.cpp index 404199102..a5206eefb 100644 --- a/src/qtmultimediaquicktools/qsgvideonode_texture.cpp +++ b/src/qtmultimediaquicktools/qsgvideonode_texture.cpp @@ -37,13 +37,13 @@ ** ****************************************************************************/ #include "qsgvideonode_texture_p.h" +#include "qsgvideotexture_p.h" #include <QtQuick/qsgtexturematerial.h> #include <QtQuick/qsgmaterial.h> #include <QtCore/qmutex.h> #include <QtGui/QOpenGLContext> #include <QtGui/QOpenGLFunctions> #include <QtOpenGL/QOpenGLShaderProgram> -#include <QtMultimedia/private/qmediaopenglhelper_p.h> #include <QtMultimedia/private/qtmultimediaglobal_p.h> QT_BEGIN_NAMESPACE @@ -127,6 +127,30 @@ protected: int m_hasAlpha; }; +class QSGVideoMaterialRhiShader_Texture : public QSGMaterialRhiShader +{ +public: + QSGVideoMaterialRhiShader_Texture() + { + setShaderFileName(VertexStage, QStringLiteral(":/qtmultimediaquicktools/shaders_ng/rgba.vert.qsb")); + setShaderFileName(FragmentStage, QStringLiteral(":/qtmultimediaquicktools/shaders_ng/rgba.frag.qsb")); + } + + bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, + QSGMaterial *oldMaterial) override; + + void updateSampledImage(RenderState &state, int binding, QSGTexture **texture, + QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override; +}; + +class QSGVideoMaterialRhiShader_Texture_swizzle : public QSGVideoMaterialRhiShader_Texture +{ +public: + QSGVideoMaterialRhiShader_Texture_swizzle() + { + setShaderFileName(FragmentStage, QStringLiteral(":/qtmultimediaquicktools/shaders_ng/bgra.frag.qsb")); + } +}; class QSGVideoMaterial_Texture : public QSGMaterial { @@ -137,6 +161,7 @@ public: m_opacity(1.0) { setFlag(Blending, false); + setFlag(SupportsRhiShader, true); } ~QSGVideoMaterial_Texture() @@ -150,6 +175,10 @@ public: } QSGMaterialShader *createShader() const override { + if (flags().testFlag(RhiShaderWanted)) + return needsSwizzling() ? new QSGVideoMaterialRhiShader_Texture_swizzle + : new QSGVideoMaterialRhiShader_Texture; + const bool hasAlpha = m_format.pixelFormat() == QVideoFrame::Format_ARGB32; return needsSwizzling() ? new QSGVideoMaterialShader_Texture_swizzle(hasAlpha) : new QSGVideoMaterialShader_Texture; @@ -202,17 +231,62 @@ public: QMutex m_frameMutex; QSize m_textureSize; QVideoSurfaceFormat m_format; - GLuint m_textureId; + quint64 m_textureId; qreal m_opacity; + QScopedPointer<QSGVideoTexture> m_texture; private: bool needsSwizzling() const { - return !QMediaOpenGLHelper::isANGLE() - && (m_format.pixelFormat() == QVideoFrame::Format_RGB32 - || m_format.pixelFormat() == QVideoFrame::Format_ARGB32); + return m_format.pixelFormat() == QVideoFrame::Format_RGB32 + || m_format.pixelFormat() == QVideoFrame::Format_ARGB32; } }; +bool QSGVideoMaterialRhiShader_Texture::updateUniformData(RenderState &state, QSGMaterial *newMaterial, + QSGMaterial *oldMaterial) +{ + Q_UNUSED(newMaterial); + Q_UNUSED(oldMaterial); + + bool changed = false; + QByteArray *buf = state.uniformData(); + + if (state.isMatrixDirty()) { + memcpy(buf->data(), state.combinedMatrix().constData(), 64); + changed = true; + } + + if (state.isOpacityDirty()) { + const float opacity = state.opacity(); + memcpy(buf->data() + 64, &opacity, 4); + changed = true; + } + + return changed; +} + +void QSGVideoMaterialRhiShader_Texture::updateSampledImage(RenderState &state, int binding, QSGTexture **texture, + QSGMaterial *newMaterial, QSGMaterial *oldMaterial) +{ + Q_UNUSED(oldMaterial); + + if (binding < 1) + return; + + auto m = static_cast<QSGVideoMaterial_Texture *>(newMaterial); + if (!m->m_texture) + m->m_texture.reset(new QSGVideoTexture); + + m->m_frameMutex.lock(); + auto size = m->m_frame.size(); + if (m->m_frame.isValid()) + m->m_textureId = m->m_frame.handle().toULongLong(); + m->m_frameMutex.unlock(); + + m->m_texture->setNativeObject(m->m_textureId, size); + m->m_texture->commitTextureOperations(state.rhi(), state.resourceUpdateBatch()); + *texture = m->m_texture.data(); +} QSGVideoNode_Texture::QSGVideoNode_Texture(const QVideoSurfaceFormat &format) : m_format(format) diff --git a/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp b/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp index 2b50e9cb0..006704a23 100644 --- a/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp +++ b/src/qtmultimediaquicktools/qsgvideonode_yuv.cpp @@ -37,6 +37,7 @@ ** ****************************************************************************/ #include "qsgvideonode_yuv_p.h" +#include "qsgvideotexture_p.h" #include <QtCore/qmutex.h> #include <QtQuick/qsgtexturematerial.h> #include <QtQuick/qsgmaterial.h> @@ -181,7 +182,6 @@ public: } }; - class QSGVideoMaterialShader_YUV_BiPlanar_swizzle : public QSGVideoMaterialShader_YUV_BiPlanar { public: @@ -192,7 +192,6 @@ public: } }; - class QSGVideoMaterialShader_YUV_TriPlanar : public QSGVideoMaterialShader_YUV_BiPlanar { public: @@ -216,6 +215,77 @@ protected: int m_id_plane3Texture; }; +class QSGVideoMaterialRhiShader_YUV : public QSGMaterialRhiShader +{ +public: + QSGVideoMaterialRhiShader_YUV() + { + setShaderFileName(VertexStage, QStringLiteral(":/qtmultimediaquicktools/shaders_ng/yuv.vert.qsb")); + } + + bool updateUniformData(RenderState &state, QSGMaterial *newMaterial, + QSGMaterial *oldMaterial) override; + + void updateSampledImage(RenderState &state, int binding, QSGTexture **texture, + QSGMaterial *newMaterial, QSGMaterial *oldMaterial) override; + + virtual void mapFrame(QSGVideoMaterial_YUV *) = 0; + +protected: + GLfloat m_planeWidth[3] = {0, 0, 0}; + QMatrix4x4 m_colorMatrix; +}; + +class QSGVideoMaterialRhiShader_UYVY : public QSGVideoMaterialRhiShader_YUV +{ +public: + QSGVideoMaterialRhiShader_UYVY() + { + setShaderFileName(FragmentStage, QStringLiteral(":/qtmultimediaquicktools/shaders_ng/uyvy.frag.qsb")); + } + + void mapFrame(QSGVideoMaterial_YUV *m) override; +}; + +class QSGVideoMaterialRhiShader_YUYV : public QSGVideoMaterialRhiShader_UYVY +{ +public: + QSGVideoMaterialRhiShader_YUYV() + { + setShaderFileName(FragmentStage, QStringLiteral(":/qtmultimediaquicktools/shaders_ng/yuyv.frag.qsb")); + } +}; + +class QSGVideoMaterialRhiShader_YUV_YV : public QSGVideoMaterialRhiShader_YUV +{ +public: + QSGVideoMaterialRhiShader_YUV_YV() + { + setShaderFileName(FragmentStage, QStringLiteral(":/qtmultimediaquicktools/shaders_ng/yuv_yv.frag.qsb")); + } + + void mapFrame(QSGVideoMaterial_YUV *m) override; +}; + +class QSGVideoMaterialRhiShader_NV12 : public QSGVideoMaterialRhiShader_YUV +{ +public: + QSGVideoMaterialRhiShader_NV12() + { + setShaderFileName(FragmentStage, QStringLiteral(":/qtmultimediaquicktools/shaders_ng/nv12.frag.qsb")); + } + + void mapFrame(QSGVideoMaterial_YUV *m) override; +}; + +class QSGVideoMaterialRhiShader_NV21 : public QSGVideoMaterialRhiShader_NV12 +{ +public: + QSGVideoMaterialRhiShader_NV21() + { + setShaderFileName(FragmentStage, QStringLiteral(":/qtmultimediaquicktools/shaders_ng/nv21.frag.qsb")); + } +}; class QSGVideoMaterial_YUV : public QSGMaterial { @@ -241,6 +311,21 @@ public: } QSGMaterialShader *createShader() const override { + if (flags().testFlag(RhiShaderWanted)) { + switch (m_format.pixelFormat()) { + case QVideoFrame::Format_NV12: + return new QSGVideoMaterialRhiShader_NV12; + case QVideoFrame::Format_NV21: + return new QSGVideoMaterialRhiShader_NV21; + case QVideoFrame::Format_UYVY: + return new QSGVideoMaterialRhiShader_UYVY; + case QVideoFrame::Format_YUYV: + return new QSGVideoMaterialRhiShader_YUYV; + default: // Currently: YUV420P, YUV422P and YV12 + return new QSGVideoMaterialRhiShader_YUV_YV; + } + } + switch (m_format.pixelFormat()) { case QVideoFrame::Format_NV12: return new QSGVideoMaterialShader_YUV_BiPlanar; @@ -293,12 +378,145 @@ public: QVideoFrame m_frame; QMutex m_frameMutex; + + QScopedPointer<QSGVideoTexture> m_textures[3]; }; +bool QSGVideoMaterialRhiShader_YUV::updateUniformData(RenderState &state, QSGMaterial *newMaterial, + QSGMaterial *oldMaterial) +{ + Q_UNUSED(oldMaterial); + + auto m = static_cast<QSGVideoMaterial_YUV *>(newMaterial); + bool changed = false; + QByteArray *buf = state.uniformData(); + + if (state.isMatrixDirty()) { + memcpy(buf->data(), state.combinedMatrix().constData(), 64); + changed = true; + } + + if (m->m_colorMatrix != m_colorMatrix) { + memcpy(buf->data() + 64, m->m_colorMatrix.constData(), 64); + changed = true; + } + m_colorMatrix = m->m_colorMatrix; + + if (state.isOpacityDirty()) { + const float opacity = state.opacity(); + memcpy(buf->data() + 64 + 64, &opacity, 4); + changed = true; + } + + if (!m->m_textures[0]) { + m->m_textures[0].reset(new QSGVideoTexture); + m->m_textures[1].reset(new QSGVideoTexture); + } + + mapFrame(m); + + if (m->m_planeWidth[0] != m_planeWidth[0] + || m->m_planeWidth[1] != m_planeWidth[1] + || m->m_planeWidth[2] != m_planeWidth[2]) + { + memcpy(buf->data() + 64 + 64 + 4, &m->m_planeWidth[0], 4); + memcpy(buf->data() + 64 + 64 + 4 + 4, &m->m_planeWidth[1], 4); + memcpy(buf->data() + 64 + 64 + 4 + 4 + 4, &m->m_planeWidth[2], 4); + changed = true; + } + m_planeWidth[0] = m->m_planeWidth[0]; + m_planeWidth[1] = m->m_planeWidth[1]; + m_planeWidth[2] = m->m_planeWidth[2]; + + return changed; +} + +void QSGVideoMaterialRhiShader_YUV::updateSampledImage(RenderState &state, int binding, QSGTexture **texture, + QSGMaterial *newMaterial, QSGMaterial *oldMaterial) +{ + Q_UNUSED(oldMaterial); + if (binding < 1 || binding > 3) + return; + + auto m = static_cast<QSGVideoMaterial_YUV *>(newMaterial); + *texture = m->m_textures[binding - 1].data(); + (*texture)->commitTextureOperations(state.rhi(), state.resourceUpdateBatch()); +} + +void QSGVideoMaterialRhiShader_UYVY::mapFrame(QSGVideoMaterial_YUV *m) +{ + if (!m->m_frame.isValid() || !m->m_frame.map(QAbstractVideoBuffer::ReadOnly)) + return; + + int fw = m->m_frame.width(); + int fh = m->m_frame.height(); + + m->m_planeWidth[0] = 1; + m->m_planeWidth[1] = 1; + + // Either r,b (YUYV) or g,a (UYVY) values are used as source of UV. + // Additionally U and V are set per 2 pixels hence only 1/2 of image width is used. + m->m_textures[0]->setData(QRhiTexture::RG8, m->m_frame.size(), + m->m_frame.bits(), m->m_frame.bytesPerLine() * fh); + m->m_textures[1]->setData(QRhiTexture::RGBA8, QSize(fw / 2, fh), + m->m_frame.bits(), m->m_frame.bytesPerLine() * fh); + + m->m_frame.unmap(); +} + +void QSGVideoMaterialRhiShader_YUV_YV::mapFrame(QSGVideoMaterial_YUV *m) +{ + if (!m->m_frame.isValid() || !m->m_frame.map(QAbstractVideoBuffer::ReadOnly)) + return; + + if (!m->m_textures[2]) + m->m_textures[2].reset(new QSGVideoTexture); + + int y = 0; + int u = m->m_frame.pixelFormat() == QVideoFrame::Format_YV12 ? 2 : 1; + int v = m->m_frame.pixelFormat() == QVideoFrame::Format_YV12 ? 1 : 2; + int fw = m->m_frame.width(); + int fh = m->m_frame.height(); + int uvHeight = m->m_frame.pixelFormat() == QVideoFrame::Format_YUV422P ? fh : fh / 2; + + m->m_planeWidth[0] = qreal(fw) / m->m_frame.bytesPerLine(y); + m->m_planeWidth[1] = m->m_planeWidth[2] = qreal(fw) / (2 * m->m_frame.bytesPerLine(u)); + + m->m_textures[0]->setData(QRhiTexture::R8, m->m_frame.size(), + m->m_frame.bits(y), m->m_frame.bytesPerLine(y) * fh); + m->m_textures[1]->setData(QRhiTexture::R8, QSize(m->m_frame.bytesPerLine(u), uvHeight), + m->m_frame.bits(u), m->m_frame.bytesPerLine(u) * uvHeight); + m->m_textures[2]->setData(QRhiTexture::R8, QSize(m->m_frame.bytesPerLine(v), uvHeight), + m->m_frame.bits(v), m->m_frame.bytesPerLine(v) * uvHeight); + + m->m_frame.unmap(); +} + +void QSGVideoMaterialRhiShader_NV12::mapFrame(QSGVideoMaterial_YUV *m) +{ + if (!m->m_frame.isValid() || !m->m_frame.map(QAbstractVideoBuffer::ReadOnly)) + return; + + int y = 0; + int uv = 1; + int fw = m->m_frame.width(); + int fh = m->m_frame.height(); + + m->m_planeWidth[0] = m->m_planeWidth[1] = qreal(fw) / m->m_frame.bytesPerLine(y); + + m->m_textures[0]->setData(QRhiTexture::R8, m->m_frame.size(), + m->m_frame.bits(y), m->m_frame.bytesPerLine(y) * fh); + m->m_textures[1]->setData(QRhiTexture::RG8, QSize(m->m_frame.bytesPerLine(uv) / 2 , fh / 2), + m->m_frame.bits(uv), m->m_frame.bytesPerLine(uv) * fh / 2); + + m->m_frame.unmap(); +} + QSGVideoMaterial_YUV::QSGVideoMaterial_YUV(const QVideoSurfaceFormat &format) : m_format(format), m_opacity(1.0) { + setFlag(SupportsRhiShader, true); memset(m_textureIds, 0, sizeof(m_textureIds)); switch (format.pixelFormat()) { diff --git a/src/qtmultimediaquicktools/qsgvideotexture.cpp b/src/qtmultimediaquicktools/qsgvideotexture.cpp new file mode 100644 index 000000000..dd31695ef --- /dev/null +++ b/src/qtmultimediaquicktools/qsgvideotexture.cpp @@ -0,0 +1,176 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qsgvideotexture_p.h" +#include <QtQuick/qsgtexturematerial.h> +#include <QtQuick/qsgmaterial.h> + +QT_BEGIN_NAMESPACE + +class QSGVideoTexturePrivate +{ + Q_DECLARE_PUBLIC(QSGVideoTexture) +public: + void updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates); + +private: + QSGVideoTexture *q_ptr = nullptr; + QRhiTexture::Format m_format; + QSize m_size; + const uchar *m_data = nullptr; + qsizetype m_bytes = 0; + + QScopedPointer<QRhiTexture> m_texture; + quint64 m_nativeObject = 0; +}; + +QSGVideoTexture::QSGVideoTexture() + : d_ptr(new QSGVideoTexturePrivate) +{ + d_ptr->q_ptr = this; +} + +QSGVideoTexture::~QSGVideoTexture() +{ +} + +qint64 QSGVideoTexture::comparisonKey() const +{ + Q_D(const QSGVideoTexture); + if (d->m_nativeObject) + return d->m_nativeObject; + + if (d->m_texture) + return qint64(qintptr(d->m_texture.data())); + + // two textures (and so materials) with not-yet-created texture underneath are never equal + return qint64(qintptr(this)); +} + +int QSGVideoTexture::textureId() const // legacy +{ + return 0; +} + +QRhiTexture *QSGVideoTexture::rhiTexture() const +{ + return d_func()->m_texture.data(); +} + +QSize QSGVideoTexture::textureSize() const +{ + return d_func()->m_size; +} + +bool QSGVideoTexture::hasAlphaChannel() const +{ + Q_D(const QSGVideoTexture); + return d->m_format == QRhiTexture::RGBA8 || d->m_format == QRhiTexture::BGRA8; +} + +bool QSGVideoTexture::hasMipmaps() const +{ + return mipmapFiltering() != QSGTexture::None; +} + +void QSGVideoTexture::bind() +{ +} + +void QSGVideoTexture::setData(QRhiTexture::Format f, const QSize &s, const uchar *data, qsizetype bytes) +{ + Q_D(QSGVideoTexture); + d->m_size = s; + d->m_format = f; + d->m_data = data; + d->m_bytes = bytes; +} + +void QSGVideoTexture::setNativeObject(quint64 obj, const QSize &s) +{ + Q_D(QSGVideoTexture); + setData(QRhiTexture::RGBA8, s, nullptr, 0); + if (d->m_nativeObject != obj) { + d->m_nativeObject = obj; + d->m_texture.reset(); + } +} + +void QSGVideoTexturePrivate::updateRhiTexture(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates) +{ + Q_Q(QSGVideoTexture); + + bool needsRebuild = m_texture && m_texture->pixelSize() != m_size; + if (!m_texture) { + QRhiTexture::Flags flags; + if (q->hasMipmaps()) + flags |= QRhiTexture::MipMapped | QRhiTexture::UsedWithGenerateMips; + + m_texture.reset(rhi->newTexture(m_format, m_size, 1, flags)); + needsRebuild = true; + } + + if (needsRebuild) { + m_texture->setPixelSize(m_size); + bool created = m_nativeObject + ? m_texture->buildFrom({m_nativeObject, 0}) + : m_texture->build(); + if (!created) { + qWarning("Failed to build texture (size %dx%d)", + m_size.width(), m_size.height()); + return; + } + } + + if (m_bytes) { + QRhiTextureSubresourceUploadDescription subresDesc(m_data, m_bytes); + subresDesc.setSourceSize(m_size); + subresDesc.setDestinationTopLeft(QPoint(0, 0)); + QRhiTextureUploadEntry entry(0, 0, subresDesc); + QRhiTextureUploadDescription desc({ entry }); + resourceUpdates->uploadTexture(m_texture.data(), desc); + } +} + +void QSGVideoTexture::commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates) +{ + d_func()->updateRhiTexture(rhi, resourceUpdates); +} + +QT_END_NAMESPACE diff --git a/src/qtmultimediaquicktools/qsgvideotexture_p.h b/src/qtmultimediaquicktools/qsgvideotexture_p.h new file mode 100644 index 000000000..6201264b6 --- /dev/null +++ b/src/qtmultimediaquicktools/qsgvideotexture_p.h @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2020 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QSGVIDEOTEXTURE_H +#define QSGVIDEOTEXTURE_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuick/QSGTexture> +#include <QImage> +#include <private/qrhi_p.h> + +QT_BEGIN_NAMESPACE + +class QSGVideoTexturePrivate; +class QSGVideoTexture : public QSGTexture +{ + Q_DECLARE_PRIVATE(QSGVideoTexture) +public: + QSGVideoTexture(); + ~QSGVideoTexture(); + + qint64 comparisonKey() const override; + int textureId() const override; + QRhiTexture *rhiTexture() const override; + QSize textureSize() const override; + bool hasAlphaChannel() const override; + bool hasMipmaps() const override; + void bind() override; + void commitTextureOperations(QRhi *rhi, QRhiResourceUpdateBatch *resourceUpdates) override; + void setData(QRhiTexture::Format f, const QSize &s, const uchar *data, qsizetype bytes); + void setNativeObject(quint64 obj, const QSize &s); + +protected: + QScopedPointer<QSGVideoTexturePrivate> d_ptr; +}; + +QT_END_NAMESPACE + +#endif // QSGVIDEOTEXTURE_H diff --git a/src/qtmultimediaquicktools/qtmultimediaquicktools.pro b/src/qtmultimediaquicktools/qtmultimediaquicktools.pro index 4f3908f6a..fefb8dec5 100644 --- a/src/qtmultimediaquicktools/qtmultimediaquicktools.pro +++ b/src/qtmultimediaquicktools/qtmultimediaquicktools.pro @@ -1,12 +1,13 @@ TARGET = QtMultimediaQuick -QT = core opengl quick multimedia-private +QT = core quick multimedia-private CONFIG += internal_module PRIVATE_HEADERS += \ qdeclarativevideooutput_p.h \ qdeclarativevideooutput_backend_p.h \ qsgvideonode_p.h \ + qsgvideotexture_p.h \ qtmultimediaquickdefs_p.h HEADERS += \ @@ -15,6 +16,7 @@ HEADERS += \ SOURCES += \ qsgvideonode_p.cpp \ + qsgvideotexture.cpp \ qdeclarativevideooutput.cpp \ qdeclarativevideooutput_window.cpp diff --git a/src/qtmultimediaquicktools/qtmultimediaquicktools.qrc b/src/qtmultimediaquicktools/qtmultimediaquicktools.qrc index b8180e31f..1c0e29c04 100644 --- a/src/qtmultimediaquicktools/qtmultimediaquicktools.qrc +++ b/src/qtmultimediaquicktools/qtmultimediaquicktools.qrc @@ -23,5 +23,15 @@ <file>shaders/triplanaryuvvideo_core.vert</file> <file>shaders/uyvyvideo_core.frag</file> <file>shaders/yuyvvideo_core.frag</file> + + <file>shaders_ng/rgba.vert.qsb</file> + <file>shaders_ng/rgba.frag.qsb</file> + <file>shaders_ng/bgra.frag.qsb</file> + <file>shaders_ng/yuv.vert.qsb</file> + <file>shaders_ng/yuv_yv.frag.qsb</file> + <file>shaders_ng/nv12.frag.qsb</file> + <file>shaders_ng/nv21.frag.qsb</file> + <file>shaders_ng/uyvy.frag.qsb</file> + <file>shaders_ng/yuyv.frag.qsb</file> </qresource> </RCC> diff --git a/src/qtmultimediaquicktools/shaders_ng/bgra.frag b/src/qtmultimediaquicktools/shaders_ng/bgra.frag new file mode 100644 index 000000000..f04e3e721 --- /dev/null +++ b/src/qtmultimediaquicktools/shaders_ng/bgra.frag @@ -0,0 +1,16 @@ +#version 440 + +layout(location = 0) in vec2 qt_TexCoord; +layout(location = 0) out vec4 fragColor; + +layout(std140, binding = 0) uniform buf { + mat4 matrix; + float opacity; +} ubuf; + +layout(binding = 1) uniform sampler2D rgbTexture; + +void main() +{ + fragColor = texture(rgbTexture, qt_TexCoord).bgra * ubuf.opacity; +} diff --git a/src/qtmultimediaquicktools/shaders_ng/bgra.frag.qsb b/src/qtmultimediaquicktools/shaders_ng/bgra.frag.qsb Binary files differnew file mode 100644 index 000000000..20c61e92f --- /dev/null +++ b/src/qtmultimediaquicktools/shaders_ng/bgra.frag.qsb diff --git a/src/qtmultimediaquicktools/shaders_ng/compile.bat b/src/qtmultimediaquicktools/shaders_ng/compile.bat new file mode 100755 index 000000000..682cc71b8 --- /dev/null +++ b/src/qtmultimediaquicktools/shaders_ng/compile.bat @@ -0,0 +1,50 @@ +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:: +:: Copyright (C) 2019 The Qt Company Ltd. +:: Contact: https://www.qt.io/licensing/ +:: +:: This file is part of the QtQuick module of the Qt Toolkit. +:: +:: $QT_BEGIN_LICENSE:LGPL$ +:: Commercial License Usage +:: Licensees holding valid commercial Qt licenses may use this file in +:: accordance with the commercial license agreement provided with the +:: Software or, alternatively, in accordance with the terms contained in +:: a written agreement between you and The Qt Company. For licensing terms +:: and conditions see https://www.qt.io/terms-conditions. For further +:: information use the contact form at https://www.qt.io/contact-us. +:: +:: GNU Lesser General Public License Usage +:: Alternatively, this file may be used under the terms of the GNU Lesser +:: General Public License version 3 as published by the Free Software +:: Foundation and appearing in the file LICENSE.LGPL3 included in the +:: packaging of this file. Please review the following information to +:: ensure the GNU Lesser General Public License version 3 requirements +:: will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +:: +:: GNU General Public License Usage +:: Alternatively, this file may be used under the terms of the GNU +:: General Public License version 2.0 or (at your option) the GNU General +:: Public license version 3 or any later version approved by the KDE Free +:: Qt Foundation. The licenses are as published by the Free Software +:: Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +:: included in the packaging of this file. Please review the following +:: information to ensure the GNU General Public License requirements will +:: be met: https://www.gnu.org/licenses/gpl-2.0.html and +:: https://www.gnu.org/licenses/gpl-3.0.html. +:: +:: $QT_END_LICENSE$ +:: +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +qsb -b --glsl "150,120,100 es" --hlsl 50 --msl 12 -o rgba.vert.qsb rgba.vert +qsb --glsl "150,120,100 es" --hlsl 50 --msl 12 -o rgba.frag.qsb rgba.frag +qsb --glsl "150,120,100 es" --hlsl 50 --msl 12 -o bgra.frag.qsb bgra.frag + +qsb -b --glsl "150,120,100 es" --hlsl 50 --msl 12 -o yuv.vert.qsb yuv.vert +qsb --glsl "150,120,100 es" --hlsl 50 --msl 12 -o yuv_yv.frag.qsb yuv_yv.frag + +qsb --glsl "150,120,100 es" --hlsl 50 --msl 12 -o nv12.frag.qsb nv12.frag +qsb --glsl "150,120,100 es" --hlsl 50 --msl 12 -o nv21.frag.qsb nv21.frag +qsb --glsl "150,120,100 es" --hlsl 50 --msl 12 -o uyvy.frag.qsb uyvy.frag +qsb --glsl "150,120,100 es" --hlsl 50 --msl 12 -o yuyv.frag.qsb yuyv.frag diff --git a/src/qtmultimediaquicktools/shaders_ng/nv12.frag b/src/qtmultimediaquicktools/shaders_ng/nv12.frag new file mode 100644 index 000000000..9ef6bd648 --- /dev/null +++ b/src/qtmultimediaquicktools/shaders_ng/nv12.frag @@ -0,0 +1,25 @@ +#version 440 + +layout(location = 0) in vec2 plane1TexCoord; +layout(location = 1) in vec2 plane2TexCoord; +layout(location = 0) out vec4 fragColor; + +layout(std140, binding = 0) uniform buf { + mat4 matrix; + mat4 colorMatrix; + float opacity; + float plane1Width; + float plane2Width; + float plane3Width; +} ubuf; + +layout(binding = 1) uniform sampler2D plane1Texture; +layout(binding = 2) uniform sampler2D plane2Texture; + +void main() +{ + float Y = texture(plane1Texture, plane1TexCoord).r; + vec2 UV = texture(plane2Texture, plane2TexCoord).rg; + vec4 color = vec4(Y, UV.x, UV.y, 1.); + fragColor = ubuf.colorMatrix * color * ubuf.opacity; +} diff --git a/src/qtmultimediaquicktools/shaders_ng/nv12.frag.qsb b/src/qtmultimediaquicktools/shaders_ng/nv12.frag.qsb Binary files differnew file mode 100644 index 000000000..f3402d460 --- /dev/null +++ b/src/qtmultimediaquicktools/shaders_ng/nv12.frag.qsb diff --git a/src/qtmultimediaquicktools/shaders_ng/nv21.frag b/src/qtmultimediaquicktools/shaders_ng/nv21.frag new file mode 100644 index 000000000..636294048 --- /dev/null +++ b/src/qtmultimediaquicktools/shaders_ng/nv21.frag @@ -0,0 +1,25 @@ +#version 440 + +layout(location = 0) in vec2 plane1TexCoord; +layout(location = 1) in vec2 plane2TexCoord; +layout(location = 0) out vec4 fragColor; + +layout(std140, binding = 0) uniform buf { + mat4 matrix; + mat4 colorMatrix; + float opacity; + float plane1Width; + float plane2Width; + float plane3Width; +} ubuf; + +layout(binding = 1) uniform sampler2D plane1Texture; +layout(binding = 2) uniform sampler2D plane2Texture; + +void main() +{ + float Y = texture(plane1Texture, plane1TexCoord).r; + vec2 UV = texture(plane2Texture, plane2TexCoord).gr; + vec4 color = vec4(Y, UV.x, UV.y, 1.); + fragColor = ubuf.colorMatrix * color * ubuf.opacity; +} diff --git a/src/qtmultimediaquicktools/shaders_ng/nv21.frag.qsb b/src/qtmultimediaquicktools/shaders_ng/nv21.frag.qsb Binary files differnew file mode 100644 index 000000000..b90af8c53 --- /dev/null +++ b/src/qtmultimediaquicktools/shaders_ng/nv21.frag.qsb diff --git a/src/qtmultimediaquicktools/shaders_ng/rgba.frag b/src/qtmultimediaquicktools/shaders_ng/rgba.frag new file mode 100644 index 000000000..1623c2cc7 --- /dev/null +++ b/src/qtmultimediaquicktools/shaders_ng/rgba.frag @@ -0,0 +1,16 @@ +#version 440 + +layout(location = 0) in vec2 qt_TexCoord; +layout(location = 0) out vec4 fragColor; + +layout(std140, binding = 0) uniform buf { + mat4 matrix; + float opacity; +} ubuf; + +layout(binding = 1) uniform sampler2D rgbTexture; + +void main() +{ + fragColor = texture(rgbTexture, qt_TexCoord) * ubuf.opacity; +} diff --git a/src/qtmultimediaquicktools/shaders_ng/rgba.frag.qsb b/src/qtmultimediaquicktools/shaders_ng/rgba.frag.qsb Binary files differnew file mode 100644 index 000000000..c1ecaa7bf --- /dev/null +++ b/src/qtmultimediaquicktools/shaders_ng/rgba.frag.qsb diff --git a/src/qtmultimediaquicktools/shaders_ng/rgba.vert b/src/qtmultimediaquicktools/shaders_ng/rgba.vert new file mode 100644 index 000000000..ebc53a65f --- /dev/null +++ b/src/qtmultimediaquicktools/shaders_ng/rgba.vert @@ -0,0 +1,18 @@ +#version 440 + +layout(location = 0) in vec4 qt_VertexPosition; +layout(location = 1) in vec2 qt_VertexTexCoord; + +layout(location = 0) out vec2 qt_TexCoord; + +layout(std140, binding = 0) uniform buf { + mat4 matrix; + float opacity; +} ubuf; + +out gl_PerVertex { vec4 gl_Position; }; + +void main() { + qt_TexCoord = qt_VertexTexCoord; + gl_Position = ubuf.matrix * qt_VertexPosition; +} diff --git a/src/qtmultimediaquicktools/shaders_ng/rgba.vert.qsb b/src/qtmultimediaquicktools/shaders_ng/rgba.vert.qsb Binary files differnew file mode 100644 index 000000000..f655df0db --- /dev/null +++ b/src/qtmultimediaquicktools/shaders_ng/rgba.vert.qsb diff --git a/src/qtmultimediaquicktools/shaders_ng/uyvy.frag b/src/qtmultimediaquicktools/shaders_ng/uyvy.frag new file mode 100644 index 000000000..f1c7c1aec --- /dev/null +++ b/src/qtmultimediaquicktools/shaders_ng/uyvy.frag @@ -0,0 +1,23 @@ +#version 440 + +layout(location = 0) in vec2 plane1TexCoord; +layout(location = 1) in vec2 plane2TexCoord; +layout(location = 0) out vec4 fragColor; + +layout(std140, binding = 0) uniform buf { + mat4 matrix; + mat4 colorMatrix; + float opacity; + float plane1Width; + float plane2Width; + float plane3Width; +} ubuf; + +layout(binding = 1) uniform sampler2D plane1Texture; +layout(binding = 2) uniform sampler2D plane2Texture; + +void main() +{ + vec3 YUV = vec3(texture(plane1Texture, plane1TexCoord).g, texture(plane2Texture, plane2TexCoord).rb); + fragColor = ubuf.colorMatrix * vec4(YUV, 1.0) * ubuf.opacity; +} diff --git a/src/qtmultimediaquicktools/shaders_ng/uyvy.frag.qsb b/src/qtmultimediaquicktools/shaders_ng/uyvy.frag.qsb Binary files differnew file mode 100644 index 000000000..902821fd3 --- /dev/null +++ b/src/qtmultimediaquicktools/shaders_ng/uyvy.frag.qsb diff --git a/src/qtmultimediaquicktools/shaders_ng/yuv.vert b/src/qtmultimediaquicktools/shaders_ng/yuv.vert new file mode 100644 index 000000000..6f103372f --- /dev/null +++ b/src/qtmultimediaquicktools/shaders_ng/yuv.vert @@ -0,0 +1,26 @@ +#version 440 + +layout(location = 0) in vec4 qt_VertexPosition; +layout(location = 1) in vec2 qt_VertexTexCoord; + +layout(location = 0) out vec2 plane1TexCoord; +layout(location = 1) out vec2 plane2TexCoord; +layout(location = 2) out vec2 plane3TexCoord; + +layout(std140, binding = 0) uniform buf { + mat4 matrix; + mat4 colorMatrix; + float opacity; + float plane1Width; + float plane2Width; + float plane3Width; +} ubuf; + +out gl_PerVertex { vec4 gl_Position; }; + +void main() { + plane1TexCoord = qt_VertexTexCoord * vec2(ubuf.plane1Width, 1); + plane2TexCoord = qt_VertexTexCoord * vec2(ubuf.plane2Width, 1); + plane3TexCoord = qt_VertexTexCoord * vec2(ubuf.plane3Width, 1); + gl_Position = ubuf.matrix * qt_VertexPosition; +} diff --git a/src/qtmultimediaquicktools/shaders_ng/yuv.vert.qsb b/src/qtmultimediaquicktools/shaders_ng/yuv.vert.qsb Binary files differnew file mode 100644 index 000000000..0cde24cf6 --- /dev/null +++ b/src/qtmultimediaquicktools/shaders_ng/yuv.vert.qsb diff --git a/src/qtmultimediaquicktools/shaders_ng/yuv_yv.frag b/src/qtmultimediaquicktools/shaders_ng/yuv_yv.frag new file mode 100644 index 000000000..07ea52aab --- /dev/null +++ b/src/qtmultimediaquicktools/shaders_ng/yuv_yv.frag @@ -0,0 +1,28 @@ +#version 440 + +layout(location = 0) in vec2 plane1TexCoord; +layout(location = 1) in vec2 plane2TexCoord; +layout(location = 2) in vec2 plane3TexCoord; +layout(location = 0) out vec4 fragColor; + +layout(std140, binding = 0) uniform buf { + mat4 matrix; + mat4 colorMatrix; + float opacity; + float plane1Width; + float plane2Width; + float plane3Width; +} ubuf; + +layout(binding = 1) uniform sampler2D plane1Texture; +layout(binding = 2) uniform sampler2D plane2Texture; +layout(binding = 3) uniform sampler2D plane3Texture; + +void main() +{ + float Y = texture(plane1Texture, plane1TexCoord).r; + float U = texture(plane2Texture, plane2TexCoord).r; + float V = texture(plane3Texture, plane3TexCoord).r; + vec4 color = vec4(Y, U, V, 1.); + fragColor = ubuf.colorMatrix * color * ubuf.opacity; +} diff --git a/src/qtmultimediaquicktools/shaders_ng/yuv_yv.frag.qsb b/src/qtmultimediaquicktools/shaders_ng/yuv_yv.frag.qsb Binary files differnew file mode 100644 index 000000000..b6e3fe366 --- /dev/null +++ b/src/qtmultimediaquicktools/shaders_ng/yuv_yv.frag.qsb diff --git a/src/qtmultimediaquicktools/shaders_ng/yuyv.frag b/src/qtmultimediaquicktools/shaders_ng/yuyv.frag new file mode 100644 index 000000000..454fdc21e --- /dev/null +++ b/src/qtmultimediaquicktools/shaders_ng/yuyv.frag @@ -0,0 +1,23 @@ +#version 440 + +layout(location = 0) in vec2 plane1TexCoord; +layout(location = 1) in vec2 plane2TexCoord; +layout(location = 0) out vec4 fragColor; + +layout(std140, binding = 0) uniform buf { + mat4 matrix; + mat4 colorMatrix; + float opacity; + float plane1Width; + float plane2Width; + float plane3Width; +} ubuf; + +layout(binding = 1) uniform sampler2D plane1Texture; +layout(binding = 2) uniform sampler2D plane2Texture; + +void main() +{ + vec3 YUV = vec3(texture(plane1Texture, plane1TexCoord).r, texture(plane2Texture, plane2TexCoord).ga); + fragColor = ubuf.colorMatrix * vec4(YUV, 1.0) * ubuf.opacity; +} diff --git a/src/qtmultimediaquicktools/shaders_ng/yuyv.frag.qsb b/src/qtmultimediaquicktools/shaders_ng/yuyv.frag.qsb Binary files differnew file mode 100644 index 000000000..543361af6 --- /dev/null +++ b/src/qtmultimediaquicktools/shaders_ng/yuyv.frag.qsb diff --git a/tests/auto/integration/qdeclarativevideooutput/tst_qdeclarativevideooutput.cpp b/tests/auto/integration/qdeclarativevideooutput/tst_qdeclarativevideooutput.cpp index 27c7d85de..b31947738 100644 --- a/tests/auto/integration/qdeclarativevideooutput/tst_qdeclarativevideooutput.cpp +++ b/tests/auto/integration/qdeclarativevideooutput/tst_qdeclarativevideooutput.cpp @@ -378,16 +378,6 @@ void tst_QDeclarativeVideoOutput::paintSurface() QImage img(rgb32ImageData, 2, 2, 8, QImage::Format_RGB32); QVERIFY(surface->present(img)); - - if (QGuiApplication::platformName() == QLatin1String("offscreen") - || QGuiApplication::platformName() == QLatin1String("minimal")) - return; - - QImage capture = window.grabWindow(); - QCOMPARE(capture.pixelColor(0, 0), QColor(rgb32ImageData[2], rgb32ImageData[1], rgb32ImageData[0], rgb32ImageData[3])); - QCOMPARE(capture.pixelColor(1, 0), QColor(rgb32ImageData[6], rgb32ImageData[5], rgb32ImageData[4], rgb32ImageData[7])); - QCOMPARE(capture.pixelColor(0, 1), QColor(rgb32ImageData[10], rgb32ImageData[9], rgb32ImageData[8], rgb32ImageData[11])); - QCOMPARE(capture.pixelColor(1, 1), QColor(rgb32ImageData[14], rgb32ImageData[13], rgb32ImageData[12], rgb32ImageData[15])); } void tst_QDeclarativeVideoOutput::sourceRect() |