C++ QtQuick2视频渲染质量和将QVideoWidget嵌入Qml
我正在开发一个基于QtQuick2的Qml应用程序,但QtMultimedia 5.0模块中包含的视频组件存在问题。应用程序应该向Qml接口添加视频,最重要的是任何黑色(背景、矩形或对象)都必须是真正的黑色,以便我可以在黑色区域上覆盖其他Qml组件C++ QtQuick2视频渲染质量和将QVideoWidget嵌入Qml,c++,video,qml,qt5,qtquick2,C++,Video,Qml,Qt5,Qtquick2,我正在开发一个基于QtQuick2的Qml应用程序,但QtMultimedia 5.0模块中包含的视频组件存在问题。应用程序应该向Qml接口添加视频,最重要的是任何黑色(背景、矩形或对象)都必须是真正的黑色,以便我可以在黑色区域上覆盖其他Qml组件 在C++ QVIEWIDGET中播放视频时,视频质量良好,所有黑区都是黑色的,但是当使用QTQuQ2视频组件时,质量有点淡黄。在Qt4.8.7中,我可以使用QdeCrativeItem和QGraphicProxyWidget轻松地使用QtQuick1
在C++ QVIEWIDGET中播放视频时,视频质量良好,所有黑区都是黑色的,但是当使用QTQuQ2视频组件时,质量有点淡黄。在Qt4.8.7中,我可以使用QdeCrativeItem和QGraphicProxyWidget轻松地使用QtQuick1实现这一点,但由于Qt5改变了QtQuick2的方式,我无法找到一种轻松嵌入widget的方式
我制作了一个自定义QAbstractVideoSurface,并将其设置为QMediaPlay->setVideoOutput
,然后通过抓取QImage并调用update()在QtQuickPaintedItem中绘制它,但仍然相同。甚至将treshold 16以下的所有qRGB更改为qRGB(0,0,0),但结果很糟糕,尤其是在淡入或淡出时
我有办法解决这个问题吗?提前谢谢
编辑1:插入的代码
import QtQuick 2.6
import QtMultimedia 5.0
Video{
id: video
width: root.width
height: root.height
property string src: "main.mp4"
source: src
autoLoad: true
autoPlay: true
fillMode: VideoOutput.PreserveAspectFit
}
带有QVideoWidget的C++代码
QMediaPlayer *player = new QMediaPlayer();
QVideoWidget *view = new QVideoWidget();
player->setVideoOutput(view);
player->play();
view->resize(700, 700);
view->show();
自定义QAbstractSurface
#include "videoframegrabber.h"
VideoFrameGrabber::VideoFrameGrabber(QObject *parent)
: QAbstractVideoSurface(parent)
, imageFormat(QImage::Format_Invalid)
{
}
QList<QVideoFrame::PixelFormat> VideoFrameGrabber::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const
{
Q_UNUSED(handleType);
return QList<QVideoFrame::PixelFormat>()
<< QVideoFrame::Format_ARGB32
<< QVideoFrame::Format_ARGB32_Premultiplied
<< QVideoFrame::Format_RGB32
<< QVideoFrame::Format_RGB24
<< QVideoFrame::Format_RGB565
<< QVideoFrame::Format_RGB555
<< QVideoFrame::Format_ARGB8565_Premultiplied
<< QVideoFrame::Format_BGRA32
<< QVideoFrame::Format_BGRA32_Premultiplied
<< QVideoFrame::Format_BGR32
<< QVideoFrame::Format_BGR24
<< QVideoFrame::Format_BGR565
<< QVideoFrame::Format_BGR555
<< QVideoFrame::Format_BGRA5658_Premultiplied
<< QVideoFrame::Format_AYUV444
<< QVideoFrame::Format_AYUV444_Premultiplied
<< QVideoFrame::Format_YUV444
<< QVideoFrame::Format_YUV420P
<< QVideoFrame::Format_YV12
<< QVideoFrame::Format_UYVY
<< QVideoFrame::Format_YUYV
<< QVideoFrame::Format_NV12
<< QVideoFrame::Format_NV21
<< QVideoFrame::Format_IMC1
<< QVideoFrame::Format_IMC2
<< QVideoFrame::Format_IMC3
<< QVideoFrame::Format_IMC4
<< QVideoFrame::Format_Y8
<< QVideoFrame::Format_Y16
<< QVideoFrame::Format_Jpeg
<< QVideoFrame::Format_CameraRaw
<< QVideoFrame::Format_AdobeDng;
}
bool VideoFrameGrabber::isFormatSupported(const QVideoSurfaceFormat &format) const
{
const QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat());
const QSize size = format.frameSize();
return imageFormat != QImage::Format_Invalid
&& !size.isEmpty()
&& format.handleType() == QAbstractVideoBuffer::NoHandle;
}
bool VideoFrameGrabber::start(const QVideoSurfaceFormat &format)
{
const QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat());
const QSize size = format.frameSize();
if (imageFormat != QImage::Format_Invalid && !size.isEmpty()) {
this->imageFormat = imageFormat;
imageSize = size;
sourceRect = format.viewport();
QAbstractVideoSurface::start(format);
//widget->updateGeometry();
//updateVideoRect();
return true;
} else {
return false;
}
}
void VideoFrameGrabber::stop()
{
currentFrame = QVideoFrame();
targetRect = QRect();
QAbstractVideoSurface::stop();
//widget->update();
}
bool VideoFrameGrabber::present(const QVideoFrame &frame)
{
if (frame.isValid())
{
QVideoFrame cloneFrame(frame);
cloneFrame.map(QAbstractVideoBuffer::ReadOnly);
const QImage image(cloneFrame.bits(),
cloneFrame.width(),
cloneFrame.height(),
QVideoFrame::imageFormatFromPixelFormat(cloneFrame .pixelFormat()));
emit frameAvailable(image); // this is very important
cloneFrame.unmap();
}
if (surfaceFormat().pixelFormat() != frame.pixelFormat()
|| surfaceFormat().frameSize() != frame.size()) {
setError(IncorrectFormatError);
stop();
return false;
} else {
currentFrame = frame;
//widget->repaint(targetRect);
return true;
}
}
#包括“videoframegrabber.h”
VideoFrameGrabber::VideoFrameGrabber(QObject*父对象)
:QAbstractVideoSurface(父级)
,imageFormat(QImage::Format_无效)
{
}
QList VideoFrameGrabber::supportedPixelFormats(QAbstractVideoBuffer::HandletType HandletType)常量
{
Q_未使用(手型);
返回QList()
一个区别可能是GPU驱动程序视频后处理在一种情况下应用,而不是在另一种情况下应用。请检查GPU是否关闭了任何视频处理。在Windows上,此功能位于Intel/Nvidia/AMD GPU控制面板中(例如,建议在英伟达设置中启用完全动态范围,在不同的上下文中授予,但我相信这可能与您的问题有关)。请同时显示两种情况下使用的代码。@rubenvb请选中编辑1。为什么这只影响Qml而不影响QVideoWidget?一个区别可能是GPU驱动程序视频后处理应用于一种情况而不是另一种情况。请检查GPU的任何视频处理是否已关闭。在Windows上,这取决于Intel/Nvidia/AMD GPU contROL面板(参见,例如,建议在英伟达设置中完全启用动态范围,在不同的上下文中授予,但我相信这可能与您的问题有关)。请同时显示您使用的代码,请使用“编辑1”。这只会影响Qml而不是QVIEWOWIDGET吗?