热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

VideoOutputQML的自定义源属性

如何解决《VideoOutputQML的自定义源属性》经验,为你挑选了1个好方法。

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

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

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

如果要扩展自己的C ++类以与VideoOutput互操作,则可以为基于QObject的类提供mediaObject属性,该属性公开具有可用QVideoRendererControl的QMediaObject派生类,也可以为基于QObject的类提供可写videoSurface属性可以接受基于QAbstractVideoSurface的类,并且可以遵循正确的协议向其提供QVideoFrame。

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

    我implmented我自己的类myFrameProvider来源于QObject具有可写的videoSurface属性。

    使一个类连接到以下类,该类将帧发送到myFrameProvider。

    实例化myFrameProvider类,并使其在与“ VideoOutput”小部件相同的QML上下文中可访问。

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



1> Jan Osch..:

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

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

FrameProvider.h

#include 
#include 
#include 

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 
#include 

 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("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("display");
    auto provider = qvariant_cast(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来自我的实际代码,因此未经测试。我希望它无论如何都能运行并显示所有需要的步骤。


推荐阅读
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了使用kotlin实现动画效果的方法,包括上下移动、放大缩小、旋转等功能。通过代码示例演示了如何使用ObjectAnimator和AnimatorSet来实现动画效果,并提供了实现抖动效果的代码。同时还介绍了如何使用translationY和translationX来实现上下和左右移动的效果。最后还提供了一个anim_small.xml文件的代码示例,可以用来实现放大缩小的效果。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • Linux重启网络命令实例及关机和重启示例教程
    本文介绍了Linux系统中重启网络命令的实例,以及使用不同方式关机和重启系统的示例教程。包括使用图形界面和控制台访问系统的方法,以及使用shutdown命令进行系统关机和重启的句法和用法。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • 怀疑是每次都在新建文件,具体代码如下 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • 本文介绍了如何在方法参数中指定一个对象的协议,以及如何调用符合该协议的方法。以一个具体的示例说明了如何在方法参数中指定一个UIView子类对象,并且该对象需要符合PixelUI协议,同时方法需要能够访问该对象的属性。 ... [详细]
author-avatar
丿车荣璇
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有