VideoOutput QML 的自定义源属性

2023-12-03

到底需要做什么才能提供自定义框架源VideoOutputQML 对象?

Does VideoOuput本身提供了一个实例QAbstractVideoSurface类到“源”?

Qt5 文档说明了有关此问题的以下内容:

如果您正在扩展自己的 C++ 类以与 VideoOutput,您可以提供一个基于 QObject 的类 mediaObject 属性公开 QMediaObject 派生类,该类 有一个可用的 QVideoRendererControl,或者您可以提供一个 QObject 具有可写 videoSurface 属性的基类,可以接受 基于 QAbstractVideoSurface 的类并且可以遵循正确的协议 向其传递 QVideoFrames。

根据以下文档,我执行了以下操作:

  1. 我实现了自己的课程myFrameProvider源自QObject具有可写的videoSurface财产。
  2. 创建一个连接到以下内容的类,将帧发送到 myFrameProvider。
  3. 实例化myFrameProvider类并使其在与“VideoOutput”小部件相同的 QML 上下文中可访问。

之后 - 每当访问“videSurface”属性时,我都会遇到段错误。 我应该设置自己的视频表面属性吗?


当我遇到类似的问题时,我偶然发现了你的问题。过了一会儿,我找到了一个对我有用的解决方案。即使您的问题是一个较旧的问题并且您可能会继续前进,我也想分享我的答案以可能对其他人有所帮助。

我在中找到了答案QT文档在“使用低级视频帧”部分中。那里发布的代码片段作为起点非常有帮助,但我必须修改它,以便它正常工作。一个最小的工作示例如下所示:

FrameProvider.h

#include <QObject>
#include <QAbstractVideoSurface>
#include <QVideoSurfaceFormat>

class FameProvider : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QAbstractVideoSurface *videoSurface READ videoSurface WRITE setVideoSurface)


public:
    QAbstractVideoSurface* videoSurface() const { return m_surface; }

private:
    QAbstractVideoSurface *m_surface = NULL;
    QVideoSurfaceFormat m_format;

public:


    void setVideoSurface(QAbstractVideoSurface *surface)
    {
        if (m_surface && m_surface != surface  && m_surface->isActive()) {
            m_surface->stop();
        }

        m_surface = surface;

        if (m_surface && m_format.isValid())
        {
            m_format = m_surface->nearestFormat(m_format);
            m_surface->start(m_format);

        }
    }

    void setFormat(int width, int heigth, int format)
    {
        QSize size(width, heigth);
        QVideoSurfaceFormat format(size, format);
        m_format = format;

        if (m_surface) 
        {
            if (m_surface->isActive())
            {
                m_surface->stop();
            }
            m_format = m_surface->nearestFormat(m_format);
            m_surface->start(m_format);
        }
    }

public slots:
    void onNewVideoContentReceived(const QVideoFrame &frame)
    {

        if (m_surface)
            m_surface->present(frame);
    }
};

main.qml

import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Controls.Material 2.2
import QtMultimedia 5.4
import com.yourcompany.FrameProvider 1.0

ApplicationWindow {
    objectName: "mainWindow"
    visible: true
    width: 640
    height: 480

    FrameProvider{
        objectName: "provider"
        id: provider
    }

    VideoOutput {
        id: display
        objectName: "display"
        anchors.top: parent.top
        anchors.bottom: parent.bottom
        width: parent.width
        source: provider
    }
}

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>

 int main(int argc, char *argv[])
{
    // initialize the qml application engine
    QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    QGuiApplication app(argc, argv);
    QQmlApplicationEngine engine;

    //register the custom control to the qml application engine
    qmlRegisterType<FameProvider>("com.yourcompany.FrameProvider", 1, 0, "FrameProvider");

    // start the view
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
    {
    return -1;
    }

    // find your custom control
    QObject *rootObject = engine.rootObjects().first();
    Qobject *display = rootObject->findChild<QObject *>("display");
    auto provider = qvariant_cast<FameProvider *>(display->property("source"));

    // Create your custom frame source class, which inherits from QObject. This source is expected to have the following public fields and signals:
    // - int width
    // - int height
    // - int format (following QVideoFrame::PixelFormat)
    // - signals: void newFrameAvailable(const QVideoFrame &frame);
    CustomFramesource source;

    // Set the correct format for the video surface (Make sure your selected format is supported by the surface)
    provider->setFormat(source.width,source.height, source.format);

    // Connect your frame source with the provider
    QObject::connect(&source, SIGNAL(newFrameAvailable(const QVideoFrame &)), provider, SLOT(onNewVideoContentReceived(const QVideoFrame &)));

    // run the app
    int retVal =  app.exec();

    return 0;
}

MWE 是从我的实际代码中浓缩而来的,因此未经测试。我希望它无论如何都能运行并显示所有需要的步骤。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

VideoOutput QML 的自定义源属性 的相关文章

随机推荐