我试图让自己成为具有更多功能的QML Camera项目,并为VideoOutput元素提供源代码。比如:
VideoOutput{
source:mycamera
}
MyCustomCamera{
id:mycamera
}
如果要扩展自己的C ++类以进行互操作 VideoOutput,你可以提供一个基于QObject的类 mediaObject属性,公开一个QMediaObject派生类 有一个QVideoRendererControl,或者你可以提供一个QObject 基于类的可写videoSurface属性,可以接受 QAbstractVideo基于表面的类并且可以遵循正确的协议 向其提供QVideoFrame。
我试过给我的对象一个私有属性mediaObject,它是QCamera类型,但看起来QCamera没有QVideoRenderControl(或者我的错,我不知道如何正确地做到这一点)。
我需要达到一开始就显示的效果,无论如何都受欢迎。
或者其他任何人都可以给我一个简短的例子,说明“一个可写的videoSurace属性,接受blablabla并遵循正确的协议”?
答案 0 :(得分:3)
我不能帮助您解决主要问题,但可以举一个videoSurface
的用法示例。您可以像这样使用“可写videoSurface
”:
我的示例包括三个主要步骤:
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!";
}
}
此类仅加载图像文件并使用计时器来显示它,但在您的情况下,您将拥有帧源,因此可以根据需要进行更改。如果您可以将框架转换为QImage
的{{1}},则可以这样显示。
您必须使此类在QML中可用。就我而言,我创建了一个对象,并通过将其设置为属性使它对QML可见。
QVideoFrame
您将此对象作为QML中的源提供给VideoOutput。
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();
}
正如我所说,这个示例是一个简单的示例,它仅加载一幅图像并且仅定期显示该图像。
这个问题是一个古老的问题,您可能会继续前进,但希望这至少可以帮助其他人。
答案 1 :(得分:0)
@U.Tuken 提供的代码工作正常,除非我将 Q_PROPERTY 中的属性名称从“videoSurface”更改为任何其他词,否则它不起作用。从 Qt 的角度来看,这是非常奇怪的行为原因,“videoSurface”只是一个名称。
另外我有错误
<块引用>"qt.gui.icc: fromIccProfile: 失败的最小标签大小健全性"。
如果导入的“JPG”格式不正确会弹出这个错误 as per this link.
更改“JPG”文件帮助我摆脱了上述警告。
感谢提供代码@U.Tuken