我正在尝试从QVideoFrame获取QCamera,使用探测来处理它,同时我需要将内容显示给QML VideoOutput。这就是我所做的:
#include <QObject>
#include <QAbstractVideoSurface>
#include <QVideoSurfaceFormat>
class FrameProvider: public QObject {
Q_OBJECT
Q_PROPERTY(QAbstractVideoSurface *videoSurface READ getVideoSurface WRITE setVideoSurface NOTIFY videoSurfaceChanged)
public:
FrameProvider(QObject *parent = nullptr)
: QObject(parent) {}
QAbstractVideoSurface* getVideoSurface() const { return m_surface; }
void setVideoSurface(QAbstractVideoSurface *surface) {
if (m_surface != surface && m_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);
}
emit videoSurfaceChanged();
}
public slots:
void setFrame(const QVideoFrame &frame) {
if (m_surface) {
//do processing
m_surface->present(frame);
}
}
signals:
void videoSurfaceChanged();
private:
QAbstractVideoSurface *m_surface = NULL;
QVideoSurfaceFormat m_format;
};FrameProvider在其getFrames方法中接收来自QVideoProbe的帧,并对其进行处理,然后将其发送到其当前()方法,以便在QML中显示。
main(...) {
//some code
auto ctxt = engine.rootContext();
auto camera = new QCamera();
camera->setCaptureMode(QCamera::CaptureVideo);
FrameProvider fp;
auto probe = new QVideoProbe();
if(probe->setSource(camera)) {
QObject::connect(probe, SIGNAL(videoFrameProbed(QVideoFrame)), &fp, SLOT(setFrame(QVideoFrame)));
}
ctxt->setContextProperty("frameProvider", &fp);
camera->start();
engine.load(url);
}在QML中,我只是将其显示为,
VideoOutput {
source: frameProvider
width: 320
height: 480
}我跟踪了QT文档,这个例子和那个例子。我得到的信号表明getFrame正在接收探测帧,但是QML窗口完全是空白的。如果平台重要的话,我正在Arch之上运行KDE等离子体。我遗漏了什么?
发布于 2020-06-15 07:18:57
好的,我找到了这个问题的答案。实际上,问题在于QCamera和VideoOutput之间的格式转换。我刚在FrameProvider中添加了这段代码,
void setFormat(int width, int height, QVideoFrame::PixelFormat frameFormat) {
QSize size(width, height);
QVideoSurfaceFormat format(size, frameFormat);
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);
}
}当新帧可用时,调用它进行转换,例如,
void setFrame(const QVideoFrame &frame) {
if (m_surface) {
//do other processing with the received frame
...
//after you are done with processing
setFormat(frame.width(), frame.height(), frame.pixelFormat());
m_surface->present(frame);
}
}这解决了我的问题。
https://stackoverflow.com/questions/62381912
复制相似问题