> 文章列表 > qt6 qml 显示yuv数据图像

qt6 qml 显示yuv数据图像

qt6 qml 显示yuv数据图像

利用qml中的VideoOutput来显示yuv数据

import QtMultimediaVideoOutput {id: videoOutputanchors.fill: parentComponent.onCompleted: {Config.setSink(videoOutput.videoSink)}}

在VideoOutput创建完成时,将VideoOutput的videoSink指针传入到c++里面

Config.cpp中的setSink函数

    Q_INVOKABLE void setSink(QObject *_Sink){qDebug() << _Sink;sink = (QVideoSink *)_Sink;emit sinkChanged();}

如果你不知道怎么将c++类添加到qml属性里:

#include <QQmlContext>
int main(int argc, char *argv[])
{·········QQmlApplicationEngine engine;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);QQmlContext *ctx = engine.rootContext();ctx->setContextProperty("Config", config);engine.load(url);·········

然后在你接收yuv数据的代码中

	static void frameCallback(void *context, unsigned char **data, const int &pix_fmt, const int &width, const int &height){Config *config = (Config *)context;if (config){if (config->frame.isNull()){QVideoFrameFormat::PixelFormat pixel;switch (pix_fmt) {case vp::__yuv420p: { pixel = QVideoFrameFormat::Format_YUV420P; }  break;default: { pixel = QVideoFrameFormat::Format_Invalid; } break;}qDebug() << pixel << width << height;config->frame.reset(new QVideoFrame(QVideoFrameFormat(QSize(width, height), pixel)));}config->frame->map(QVideoFrame::ReadWrite);for(int i = 0; i < config->frame->planeCount(); i ++) {memcpy(config->frame->bits(i), data[i], config->frame->mappedBytes(i));}config->frame->unmap();if (config->sink)emit config->sink->videoFrameChanged(*config->frame.data());}}

config->frame为QVideoFrame
这里只针对yuv420p进行初始化
在QVideoFrame初始化的时候, QVideoFrameFormat::PixelFormat对应你的图像数据格式

按照以往的方法,先将yuv转为rgb然后在传入QQuickImageProvider
在qml通过Image来显示
这样的方法比较麻烦,现在通过VideoOutput显示将节省很多代码
性能的话没有做测试对比

VideoOutput输出的图像比例可以调整fillMode属性

注意在.pro添加multimedia模块

素描画基础网