Я работаю над приложением Qml, основанным на QtQuick2, и у меня возникают проблемы с компонентом Video, включенным в модуль QtMultimedia 5.0.Предполагается, что приложение добавляет видео в интерфейс Qml, и что наиболее важно, любой ЧЕРНЫЙ цвет (фон, прямоугольник или объект) должен быть ДЕЙСТВИТЕЛЬНО ЧЕРНЫМ, чтобы я мог наложить другие компоненты Qml на черные области.
Когда видеовоспроизводится в C ++ QvideWidget, качество видео хорошее, и вся черная область действительно черная, но когда я использую компонент QtQuick2 Video, качество немного желтоватое.Мне было легко это сделать в Qt 4.8.7 с QtQuick1, используя QDeclarativeItem и QGraphicProxyWidget, но так как Qt5 изменил способ QtQuick2, я не смог найти способ легко встроить виджет.
Я сделалпользовательский QAbstractVideoSurface и установите его как QMediaPlay->setVideoOutput
, и нарисуйте его в QtQuickPaintedItem, захватывая QImage и вызывая update (), но все равно.Даже поменял все qRGB ниже порога 16 на 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
}
C ++ код с QVideoWidget
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;
}
}