/**************************************************************************** ** ** Copyright (C) 2021 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** Commercial License Usage ** Licensees holding valid commercial Qt licenses may use this file in ** accordance with the commercial license agreement provided with the ** Software or, alternatively, in accordance with the terms contained in ** a written agreement between you and The Qt Company. For licensing terms ** and conditions see https://www.qt.io/terms-conditions. For further ** information use the contact form at https://www.qt.io/contact-us. ** ** GNU Lesser General Public License Usage ** Alternatively, this file may be used under the terms of the GNU Lesser ** General Public License version 3 as published by the Free Software ** Foundation and appearing in the file LICENSE.LGPL3 included in the ** packaging of this file. Please review the following information to ** ensure the GNU Lesser General Public License version 3 requirements ** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. ** ** GNU General Public License Usage ** Alternatively, this file may be used under the terms of the GNU ** General Public License version 2.0 or (at your option) the GNU General ** Public license version 3 or any later version approved by the KDE Free ** Qt Foundation. The licenses are as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-2.0.html and ** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ #include #include "qvideowidget_p.h" #include #include #include #include #include #include #include #include #include #include #include #include #ifdef Q_OS_WIN #include #endif using namespace Qt; QT_BEGIN_NAMESPACE void QVideoWidgetPrivate::_q_newFrame(const QVideoFrame &frame) { lastFrame = frame; q_ptr->update(); } /*! \class QVideoWidget \brief The QVideoWidget class provides a widget which presents video produced by a media object. \ingroup multimedia \inmodule QtMultimediaWidgets Attaching a QVideoWidget to a QMediaPlayer or QCamera allows it to display the video or image output of that object. \snippet multimedia-snippets/video.cpp Video widget \b {Note}: Only a single display output can be attached to a media object at one time. \sa QCamera, QMediaPlayer, QGraphicsVideoItem */ /*! Constructs a new video widget. The \a parent is passed to QWidget. */ QVideoWidget::QVideoWidget(QWidget *parent) : QWidget(parent, {}) , d_ptr(new QVideoWidgetPrivate) { d_ptr->q_ptr = this; d_ptr->videoSink = new QVideoSink(this); d_ptr->videoSink->setTargetRect(rect()); d_ptr->videoSink->setNativeWindowId(winId()); connect(d_ptr->videoSink, SIGNAL(newVideoFrame(const QVideoFrame &)), this, SLOT(_q_newFrame(const QVideoFrame &))); // connect(d_ptr->videoSink, &QVideoSink::brightnessChanged, this, &QVideoWidget::brightnessChanged); // connect(d_ptr->videoSink, &QVideoSink::contrastChanged, this, &QVideoWidget::contrastChanged); // connect(d_ptr->videoSink, &QVideoSink::hueChanged, this, &QVideoWidget::hueChanged); // connect(d_ptr->videoSink, &QVideoSink::saturationChanged, this, &QVideoWidget::saturationChanged); } /*! Destroys a video widget. */ QVideoWidget::~QVideoWidget() { delete d_ptr; } QVideoSink *QVideoWidget::videoSink() const { return d_ptr->videoSink; } /*! \property QVideoWidget::aspectRatioMode \brief how video is scaled with respect to its aspect ratio. */ Qt::AspectRatioMode QVideoWidget::aspectRatioMode() const { return d_func()->aspectRatioMode; } void QVideoWidget::setAspectRatioMode(Qt::AspectRatioMode mode) { Q_D(QVideoWidget); if (mode == d->aspectRatioMode) return; d->aspectRatioMode = mode; d->videoSink->setAspectRatioMode(mode); emit aspectRatioModeChanged(mode); } /*! \property QVideoWidget::fullScreen \brief whether video display is confined to a window or is fullScreen. */ void QVideoWidget::setFullScreen(bool fullScreen) { Q_D(QVideoWidget); Qt::WindowFlags flags = windowFlags(); if (fullScreen) { d->nonFullScreenFlags = flags & (Qt::Window | Qt::SubWindow); flags |= Qt::Window; flags &= ~Qt::SubWindow; setWindowFlags(flags); showFullScreen(); } else { flags &= ~(Qt::Window | Qt::SubWindow); //clear the flags... flags |= d->nonFullScreenFlags; //then we reset the flags (window and subwindow) setWindowFlags(flags); showNormal(); } d->wasFullScreen = fullScreen; d->videoSink->setFullScreen(fullScreen); } /*! \fn QVideoWidget::fullScreenChanged(bool fullScreen) Signals that the \a fullScreen mode of a video widget has changed. \sa isFullScreen() */ /*! Returns the size hint for the current back end, if there is one, or else the size hint from QWidget. */ QSize QVideoWidget::sizeHint() const { Q_D(const QVideoWidget); if (d->videoSink) { auto size = d->videoSink->videoSize(); if (size.isValid()) return size; } return QWidget::sizeHint(); } /*! \reimp Current event \a event. Returns the value of the base class QWidget::event(QEvent *event) function. */ bool QVideoWidget::event(QEvent *event) { Q_D(QVideoWidget); if (event->type() == QEvent::WindowStateChange) { if (windowState() & Qt::WindowFullScreen) { d->videoSink->setFullScreen(true); d->videoSink->setTargetRect(QRectF(0, 0, window()->width(), window()->height())); if (!d->wasFullScreen) emit fullScreenChanged(d->wasFullScreen = true); } else { d->videoSink->setFullScreen(false); if (d->wasFullScreen) emit fullScreenChanged(d->wasFullScreen = false); } } return QWidget::event(event); } /*! \reimp Handles the show \a event. */ void QVideoWidget::showEvent(QShowEvent *event) { QWidget::showEvent(event); } /*! \reimp Handles the hide \a event. */ void QVideoWidget::hideEvent(QHideEvent *event) { QWidget::hideEvent(event); } /*! \reimp Handles the resize \a event. */ void QVideoWidget::resizeEvent(QResizeEvent *event) { d_ptr->videoSink->setTargetRect(QRectF(0, 0, event->size().width(), event->size().height())); QWidget::resizeEvent(event); } /*! \reimp Handles the move \a event. */ void QVideoWidget::moveEvent(QMoveEvent * /*event*/) { } /*! \reimp Handles the paint \a event. */ void QVideoWidget::paintEvent(QPaintEvent *event) { Q_D(QVideoWidget); if (d->videoSink && d->lastFrame.isValid()) { QPainter painter(this); d->videoSink->paint(&painter, d->lastFrame); return; } else if (testAttribute(Qt::WA_OpaquePaintEvent)) { QPainter painter(this); painter.fillRect(event->rect(), Qt::black); } } #if defined(Q_OS_WIN) bool QVideoWidget::nativeEvent(const QByteArray &eventType, void *message, qintptr *result) { Q_D(QVideoWidget); Q_UNUSED(eventType); Q_UNUSED(result); MSG *mes = reinterpret_cast(message); if (mes->message == WM_PAINT || mes->message == WM_ERASEBKGND) { // if (d->windowBackend) // d->windowBackend->showEvent(); } return false; } #endif QT_END_NAMESPACE #include "moc_qvideowidget.cpp"