QtQuick2 Качество рендеринга видео и встраивание QVideoWidget в Qml - PullRequest
1 голос
/ 22 сентября 2019

Я работаю над приложением 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), но результат плохой, особенно при постепенном или постепенном исчезновении.

Можно ли как-нибудь это исправить?Заранее спасибо

Video playing in VLC (good black background)

Video playing in QVideoWidget (good quality black background)

Video playing in Qml Video QtMultimedia 5.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;
    }
}
...