Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QVideoSurfaceFormat setMirrored did not work out.



  • I have already created a frame provider class for QML VideoOutput component to display screen info on application. And I called the setMirrored function to set the frame to be mirrored.
    It works very well, but when I click full screen button, the mirror property no longer works. It reset to no mirrored state. Where did i go wrong? Is this a bug?
    The following code is an example to demonstrate the problem.

    #ifndef FRAMEPROVIDER_H
    #define FRAMEPROVIDER_H
    
    #include <QObject>
    #include <QTimer>
    #include <QDebug>
    #include <QPixmap>
    #include <QScreen>
    #include <QGuiApplication>
    #include <QVideoSurfaceFormat>
    #include <QAbstractVideoSurface>
    
    class FrameProvider : public QObject
    {
        Q_OBJECT
        Q_PROPERTY(QAbstractVideoSurface *videoSurface READ videoSurface WRITE setVideoSurface)
    
    public:
        explicit FrameProvider(QObject *parent = nullptr)
            : QObject(parent)
            , m_videoFormat(QSize(0, 0), QVideoFrame::Format_ARGB32)
            , m_videoSurface(nullptr)
    
        {
            connect(&m_captureTimer, &QTimer::timeout, this, &FrameProvider::screenCapture);
        }
    
        ~FrameProvider()
        {
    
        }
    
        QAbstractVideoSurface* videoSurface() const
        {
            return m_videoSurface;
        }
    
        void setVideoSurface(QAbstractVideoSurface* videoSurface)
        {
            if (m_videoSurface == videoSurface)
                return;
    
            if (m_videoSurface && m_videoSurface->isActive())
                m_videoSurface->stop();
    
            m_videoSurface = videoSurface;
    
            m_videoFormat.setMirrored(true);
    
            if (m_videoSurface)
                m_videoSurface->start(m_videoFormat);
    
            m_captureTimer.start(200);
        }
    
    public slots:
        void screenCapture()
        {
            // capture main screen picture
            auto screens = QGuiApplication::screens();
            auto screen = screens.at(0);
    #ifdef Q_OS_WIN32
            QPixmap pixmap = screen->grabWindow(0);
    #else
            QPixmap pixmap = screen->grabWindow(0, screen->geometry().x(), screen->geometry().y(),
                                                screen->geometry().width(), screen->geometry().height());
    #endif
            QImage image(pixmap.toImage().convertToFormat(QImage::Format_RGB32));
            QVideoFrame frame(image);
    
    
            QMetaObject::invokeMethod(this, "onScreenCaptured", Qt::AutoConnection,
                                      Q_ARG(QVideoFrame, frame),
                                      Q_ARG(QSize, image.size()));
        }
    
        void onScreenCaptured(const QVideoFrame& frame, const QSize &videoSize)
        {
            if (m_videoFormat.frameSize() != videoSize) {
                m_videoSurface->stop();
                m_videoFormat.setFrameSize(videoSize);
                m_videoSurface->start(m_videoFormat);
            }
    
            if (m_videoSurface)
                m_videoSurface->present(frame);
        }
    
    private:
        QVideoSurfaceFormat     m_videoFormat;
        QAbstractVideoSurface*  m_videoSurface;
        QTimer                  m_captureTimer;
    
    };
    
    #endif // FRAMEPROVIDER_H
    

    My QML file code:

    import QtQuick 2.12
    import QtQuick.Window 2.12
    import QtMultimedia 5.12
    import Company.App.FrameProvider 1.0
    
    Window {
        visible: true
        width: 640
        height: 480
        title: qsTr("Hello World")
    
        FrameProvider {
            id: frameProvier
        }
    
        VideoOutput {
            anchors.fill: parent
            source: frameProvier
        }
    }
    

    main.cpp

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include "frame_provider.h"
    
    int main(int argc, char *argv[])
    {
        QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    
        QGuiApplication app(argc, argv);
    
        QQmlApplicationEngine engine;
    
        qmlRegisterType<FrameProvider>("Company.App.FrameProvider", 1, 0, "FrameProvider");
    
        const QUrl url(QStringLiteral("qrc:/main.qml"));
        QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
                         &app, [url](QObject *obj, const QUrl &objUrl) {
            if (!obj && url == objUrl)
                QCoreApplication::exit(-1);
        }, Qt::QueuedConnection);
        engine.load(url);
    
        return app.exec();
    }
    


  • I have no idea to resolve this problem, can anyone help me. Thanks.


  • Lifetime Qt Champion

    Hi,

    This sounds like a bug...

    Which version of Qt are you using ?
    On which OS ?



  • @SGaist

    Qt version:
    Qt 5.14.1/5.14.2

    System version:
    Windows 10 Pro 1909/ Windows 10 Home 2004
    macOS 10.15.x


  • Lifetime Qt Champion

    Can you try with 5.15 ?



  • @SGaist Qt 5.15 has the same problem.


  • Lifetime Qt Champion

    The you should check the bug report system to see if it's something known. If not please consider opening a report providing a minimal compilable example that reproduces the behaviour.


Log in to reply