QAbstractVideoSurface 示例 [英] QAbstractVideoSurface example

查看:57
本文介绍了QAbstractVideoSurface 示例的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试让自己成为一个具有更多功能的 QML 相机项目,并为 VideoOutput 元素提供源.比如这个:

I'm trying to make myself a QML Camera item which has more functions, and also provide a source to the VideoOutput element. Such as this:

VideoOutput{
    source:mycamera
}
MyCustomCamera{
    id:mycamera
}

在它说的文档中

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

If you are extending your own C++ classes to interoperate with VideoOutput, you can either provide a QObject based class with a mediaObject property that exposes a QMediaObject derived class that has a QVideoRendererControl available, or you can provide a QObject based class with a writable videoSurface property that can accept a QAbstractVideoSurface based class and can follow the correct protocol to deliver QVideoFrames to it.

我尝试给我的对象一个私有属性 mediaObject,它是 QCamera 类型,但看起来 QCamera 没有 QVideoRenderControl(或者是我的错,不知道如何正确执行).

I have tried giving my object a private property mediaObject, which is of type QCamera, but looks like QCamera does not have a QVideoRenderControl (or its my fault not knowing how to do it correctly).

我要达到一开始的效果,反正欢迎.

I need to achieve the effect I've shown in the beginning, anyway is welcomed.

或者,谁能给我一个简短的例子,说明接受 blablabla 并遵循正确协议的可写 videoSurace 属性"是什么意思?

Or otherwise can anyone give me a short example on what is meant by "a writable videoSurace property that accept blablabla and follow the correct protocol"?

推荐答案

我无法帮助您解决您的主要问题,但我可以为您提供 videoSurface 的示例用法.您可以使用可写 videoSurface" 像这样:

I can't help you with your main concern but i can give you an example usage of the videoSurface.You can use the "writable videoSurface" like this:

我的示例包含三个主要步骤:

My example consists of three main steps:

  1. 您编写了一个具有 QAbstactVideoSurface 属性的类.此类将成为您的视频提供者,它可以通过调用其 present() 函数在 VideoOutput 上显示帧.

videoadapter.h

#ifndef VIDEOADAPTER_H
#define VIDEOADAPTER_H
#include <QObject>
#include <QAbstractVideoSurface>
#include <QVideoSurfaceFormat>
#include <QTimer>

class VideoAdapter : public QObject
{
  Q_OBJECT
  Q_PROPERTY(QAbstractVideoSurface* videoSurface READ videoSurface WRITE setVideoSurface NOTIFY signalVideoSurfaceChanged)
public:
  explicit VideoAdapter(QObject *parent = nullptr);

  QAbstractVideoSurface *videoSurface() const;
  void setVideoSurface(QAbstractVideoSurface *videoSurface);

signals:
  void signalVideoSurfaceChanged();

private slots:
  void slotTick();

private:
  void startSurface();

private:
  QAbstractVideoSurface *mVideoSurface;
  QVideoSurfaceFormat *mSurfaceFormat;
  QImage *mImage;
  QTimer mTimer;
};

#endif // VIDEOADAPTER_H

videoadapter.cpp

#include "videoadapter.h"
#include <QDebug>

VideoAdapter::VideoAdapter(QObject *parent)
  : QObject(parent), mVideoSurface(nullptr), mSurfaceFormat(nullptr)
{
  mTimer.setInterval(1000);
  connect(&mTimer, &QTimer::timeout, this, &VideoAdapter::slotTick);
}

QAbstractVideoSurface *VideoAdapter::videoSurface() const
{
  return mVideoSurface;
}

void VideoAdapter::setVideoSurface(QAbstractVideoSurface *videoSurface)
{
  if(videoSurface != mVideoSurface)
  {
    mVideoSurface = videoSurface;
    emit signalVideoSurfaceChanged();
    startSurface();

    // This is the test timer that will tick for us to present the image
    // on the video surface
    mTimer.start();
  }
}

void VideoAdapter::slotTick()
{
  QVideoFrame frame(*mImage);
  mVideoSurface->present(frame);
}

void VideoAdapter::startSurface()
{
  mImage = new QImage("../resources/images/test.jpg");
  auto pixelFormat = QVideoFrame::pixelFormatFromImageFormat(mImage->format());
  mSurfaceFormat = new QVideoSurfaceFormat(mImage->size(), pixelFormat);
  if(!mVideoSurface->start(*mSurfaceFormat))
  {
    qDebug() << "Surface couldn't be started!";
  }
}

这个类只加载一个图像文件并使用计时器显示它,但在您的情况下,您将拥有一个帧源,因此您可以更改它以满足您的需要.如果您可以将您的帧转换为 QVideoFrameQImage,您可以像这样显示它.

This class only loads an image file and displays it with the usage of a timer but in your case you will be having a frame source so you can change this to suit your needs. If you can convert your frame to QImage of QVideoFrame you can display it like this.

  1. 你必须让这个类在 QML 中可用.就我而言,我创建了一个对象,并通过将其设置为属性使其对 QML 可见.

  1. You have to make this class usable in QML. In my case i created an object and made it visible to QML via setting it as a property.

int main(int argc, char *argv[])
{
  QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);

  QGuiApplication app(argc, argv);

  QQmlApplicationEngine engine;

  QQmlDebuggingEnabler enabler;

  VideoAdapter adapter;
  // When you do this this object is made visible to QML context with the
  // given name
  engine.rootContext()->setContextProperty("videoAdapter", &adapter);

  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();
}

  • 您将此对象作为 QML 中的源提供给 VideoOutput.

  • You give this object to the VideoOutput as source in QML.

    Window {
      visible: true
      width: 640
      height: 480
      color: "black"
      title: qsTr("Video Player")
    
      VideoOutput {
        id: videoPlayer
        anchors.fill: parent
        source: videoAdapter
      }
    }
    

  • 我所说的这个例子是一个简单的例子,它只加载一张图片,并且只定期显示一张图片.

    This example as i said is a simple one that only loads an image and only displays that one image periodically.

    这个问题是个老问题,你可能已经继续了,但希望这至少可以帮助其他人.

    This question is an old one and you probably moved on but hope this can at least help other people.

    这篇关于QAbstractVideoSurface 示例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆