|
#include "windowhole.h" |
|
#include <QAbstractVideoSurface> |
|
#include <QApplication> |
|
#include <QDebug> |
|
#include <QDesktopWidget> |
|
#include <QQuickItem> |
|
#include <QScreen> |
|
#include <QTimer> |
|
#include <QVideoSurfaceFormat> |
|
|
|
WindowHole::WindowHole(QObject* parent) |
|
: QObject(parent) |
|
, m_desktopWidget(qApp->desktop()) |
|
, m_timer(new QTimer(this)) |
|
, m_primaryScreen(qApp->primaryScreen()) |
|
{ |
|
m_timer->setInterval(8); |
|
connect(m_timer, &QTimer::timeout, this, &WindowHole::presentFrame); |
|
} |
|
|
|
QAbstractVideoSurface* WindowHole::videoSurface() const |
|
{ |
|
return m_videoSurface; |
|
} |
|
|
|
void WindowHole::setVideoSurface(QAbstractVideoSurface* videoSurface) |
|
{ |
|
qDebug() << "setVideoSurface" << videoSurface << parent(); |
|
if (m_videoSurface == videoSurface) |
|
return; |
|
|
|
m_videoSurface = videoSurface; |
|
emit videoSurfaceChanged(); |
|
|
|
if (m_completed) |
|
startSurface(); |
|
} |
|
|
|
void WindowHole::classBegin() |
|
{ |
|
} |
|
|
|
void WindowHole::componentComplete() |
|
{ |
|
m_parentItem = qobject_cast<QQuickItem*>(parent()); |
|
|
|
connect(m_parentItem, &QQuickItem::widthChanged, this, &WindowHole::parentSizeChanged); |
|
connect(m_parentItem, &QQuickItem::heightChanged, this, &WindowHole::parentSizeChanged); |
|
} |
|
|
|
void WindowHole::parentSizeChanged() |
|
{ |
|
m_completed = true; |
|
if (!m_parentItem->width() == 0) |
|
startSurface(); |
|
} |
|
|
|
QPixmap WindowHole::grabDesktopPixmap() |
|
{ |
|
QPointF mappedPos = m_parentItem->mapToGlobal({ 0, 0 }); |
|
QRect sourceRect = QRectF(mappedPos, QSizeF{ m_parentItem->width(), m_parentItem->height() }).toRect(); |
|
return m_primaryScreen->grabWindow(0, sourceRect.x(), sourceRect.y(), sourceRect.width(), sourceRect.height()); |
|
} |
|
|
|
void WindowHole::startSurface() |
|
{ |
|
if (!m_videoSurface) { |
|
m_timer->stop(); |
|
return; |
|
} |
|
|
|
QImage image = grabDesktopPixmap().toImage(); |
|
auto pixelFormat = QVideoFrame::pixelFormatFromImageFormat(image.format()); |
|
pixelFormat = QVideoFrame::Format_ARGB32; |
|
QVideoSurfaceFormat format(QSizeF{ m_parentItem->width(), m_parentItem->height() }.toSize(), pixelFormat, QAbstractVideoBuffer::NoHandle); |
|
m_videoSurface->start(format); |
|
m_timer->start(); |
|
} |
|
|
|
void WindowHole::presentFrame() |
|
{ |
|
QImage image = grabDesktopPixmap().toImage(); |
|
image = image.convertToFormat(QImage::Format_ARGB32); |
|
QVideoFrame videoFrame(image); |
|
m_videoSurface->present(videoFrame); |
|
} |