本文介绍了VideoOutput QML的自定义源属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

VideoOutput QML对象提供自定义帧源到底需要做什么?

What exactly has to be done to provide custom source of frames for VideoOutput QML object?

VideoOuput本身是否向源"提供QAbstractVideoSurface类的实例?

Does VideoOuput itself provide an instance of QAbstractVideoSurface class to the "source"?

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

The Qt5 documentations says following thing about providing about this issue:

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

In accordance to following documentation I did the following:

  1. 我实现了自己的类myFrameProvider,该类是从QObject派生的,该类具有可写的videoSurface属性.
  2. 使一个与以下内容相关的类将帧发送到myFrameProvider.
  3. 实例化了myFrameProvider类,并使其在与"VideoOutput"小部件相同的QML上下文中可访问.
  1. I implmented my own class myFrameProvider derived from QObject that has writable videoSurface property.
  2. Make a class connected to the following that sends frames to myFrameProvider.
  3. Instantianted myFrameProvider class and made it accessible in the same QML context as `VideoOutput' widget.

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

After that - I'm getting the segfault whenever "videSurface" property is accessed.Should I set my own video surface property??

推荐答案

在遇到类似问题时,我偶然发现了您的问题.不久之后,我找到了一个对我有用的解决方案.即使您的问题比较老,并且您可能继续前进,我也想分享我的答案,以帮助其他人.

While having a similar problem, I stumbled across your question. A bit after, I found a solution, which worked for me. Even if your question is an older one and you probably moved on, I want to share my answer to potentially help other people.

我在工作"部分的 QT文档中找到了答案.低级视频帧".此处发布的这段代码非常有用,但是我必须对其进行修改,以使其正常运行.一个最小的工作示例如下:

I found the answer in the QT documentation in the section "Working with Low Level Video Frames". The piece of code posted there, was very helpful as starting point, but I had to modify it, so that it woks properly. A minimal working example looks like this:

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来自我的实际代码,因此未经测试.我希望它无论如何都能运行并显示所有需要的步骤.

The MWE is condensed from my actual code and thus untested. I hope it runs anyway and shows all needed steps.

这篇关于VideoOutput QML的自定义源属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-29 23:56
查看更多