summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLars Knoll <lars.knoll@qt.io>2021-07-29 16:02:32 +0200
committerLars Knoll <lars.knoll@qt.io>2021-08-04 07:52:11 +0200
commit86357212fe49dd3471d398a4dc8605c6cdf46406 (patch)
treef45276149dfb4a4d6c4448e1011436f0d22fd251 /src
parent2575d91f3df0405638325d71d3d0e3f1130881df (diff)
Improve windowed rendering with gstreamer
Correctly respect the aspectRatioMode when calculating the render rectangle. This works fine on xvimagesink. The vaapisink doesn't fully respect it (at least with current AMD drivers), but that is a bug in the vaapi implementation. Set the fullscreen flag on the sink when going fullscreen, so that it can apply any possible optimizations. Clean up the code dealing with brightness correction etc, as that is currently not used or supported. Change-Id: I8e4d005901fa1ee59892d647f9359d8edb96664e Reviewed-by: André de la Rocha <andre.rocha@qt.io> Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstreamervideooverlay.cpp198
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstreamervideooverlay_p.h13
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstreamervideosink.cpp21
-rw-r--r--src/multimedia/platform/gstreamer/common/qgstreamervideosink_p.h5
-rw-r--r--src/multimediawidgets/qvideowidget.cpp122
-rw-r--r--src/multimediawidgets/qvideowidget.h1
-rw-r--r--src/multimediawidgets/qvideowidget_p.h7
7 files changed, 30 insertions, 337 deletions
diff --git a/src/multimedia/platform/gstreamer/common/qgstreamervideooverlay.cpp b/src/multimedia/platform/gstreamer/common/qgstreamervideooverlay.cpp
index b98b6be71..55299215b 100644
--- a/src/multimedia/platform/gstreamer/common/qgstreamervideooverlay.cpp
+++ b/src/multimedia/platform/gstreamer/common/qgstreamervideooverlay.cpp
@@ -64,157 +64,8 @@ static constexpr ElementMap elementMap[] =
{ "xcb", "ximagesink" },
// wayland
- { "wayland", "vaapisink" }
-};
-
-class QGstreamerSinkProperties
-{
-public:
- virtual ~QGstreamerSinkProperties() = default;
-
- virtual void reset() = 0;
- virtual bool setBrightness(float brightness) = 0;
- virtual bool setContrast(float contrast) = 0;
- virtual bool setHue(float hue) = 0;
- virtual bool setSaturation(float saturation) = 0;
- virtual void setAspectRatioMode(Qt::AspectRatioMode mode) = 0;
-};
-
-class QXVImageSinkProperties : public QGstreamerSinkProperties
-{
-public:
- QXVImageSinkProperties(const QGstElement &sink)
- : m_videoSink(sink)
- {
- auto *klass = G_OBJECT_GET_CLASS(m_videoSink.object());
- m_hasForceAspectRatio = g_object_class_find_property(klass, "force-aspect-ratio");
- m_hasBrightness = g_object_class_find_property(klass, "brightness");
- m_hasContrast = g_object_class_find_property(klass, "contrast");
- m_hasHue = g_object_class_find_property(klass, "hue");
- m_hasSaturation = g_object_class_find_property(klass, "saturation");
- }
-
- void reset() override
- {
- setAspectRatioMode(m_aspectRatioMode);
- setBrightness(m_brightness);
- setContrast(m_contrast);
- setHue(m_hue);
- setSaturation(m_saturation);
- }
-
- bool setBrightness(float brightness) override
- {
- m_brightness = brightness;
- if (m_hasBrightness)
- m_videoSink.set("brightness", (int)brightness * 1000);
-
- return m_hasBrightness;
- }
-
- bool setContrast(float contrast) override
- {
- m_contrast = contrast;
- if (m_hasContrast)
- m_videoSink.set("contrast", (int)contrast * 1000);
-
- return m_hasContrast;
- }
-
- bool setHue(float hue) override
- {
- m_hue = hue;
- if (m_hasHue)
- m_videoSink.set("hue", (int)hue * 1000);
-
- return m_hasHue;
- }
-
- bool setSaturation(float saturation) override
- {
- m_saturation = saturation;
- if (m_hasSaturation)
- m_videoSink.set("saturation", (int)saturation * 1000);
-
- return m_hasSaturation;
- }
-
- void setAspectRatioMode(Qt::AspectRatioMode mode) override
- {
- m_aspectRatioMode = mode;
- if (m_hasForceAspectRatio)
- m_videoSink.set("force-aspect-ratio", (mode == Qt::KeepAspectRatio));
- }
-
-protected:
-
- QGstElement m_videoSink;
- bool m_hasForceAspectRatio = false;
- bool m_hasBrightness = false;
- bool m_hasContrast = false;
- bool m_hasHue = false;
- bool m_hasSaturation = false;
- Qt::AspectRatioMode m_aspectRatioMode = Qt::KeepAspectRatio;
- float m_brightness = 0;
- float m_contrast = 0;
- float m_hue = 0;
- float m_saturation = 0;
-};
-
-class QVaapiSinkProperties : public QXVImageSinkProperties
-{
-public:
- QVaapiSinkProperties(QGstElement sink)
- : QXVImageSinkProperties(sink)
- {
- // Set default values.
- m_contrast = 1;
- m_saturation = 1;
- }
-
- bool setBrightness(float brightness) override
- {
- m_brightness = brightness;
- if (m_hasBrightness) {
- gfloat v = brightness;
- m_videoSink.set("brightness", v);
- }
-
- return m_hasBrightness;
- }
-
- bool setContrast(float contrast) override
- {
- m_contrast = contrast;
- if (m_hasContrast) {
- gfloat v = contrast + 1; // [-1, 1] -> [0,2]
- m_videoSink.set("contrast", v);
- }
-
- return m_hasContrast;
- }
-
- bool setHue(float hue) override
- {
- m_hue = hue;
- if (m_hasHue) {
- gfloat v = hue * 180; // [-1,1] -> [-180,180]
- m_videoSink.set("hue", v);
- }
-
- return m_hasHue;
- }
-
- bool setSaturation(float saturation) override
- {
- m_saturation = saturation;
- if (m_hasSaturation) {
- gfloat v = saturation + 1; // [-100,100] -> [0,2]
- m_videoSink.set("saturation", v);
- }
-
- return m_hasSaturation;
- }
+ { "wayland", "vaapisink" },
+ { "wayland", "waylandsink" }
};
static bool qt_gst_element_is_functioning(QGstElement element)
@@ -246,7 +97,7 @@ static QGstElement findBestVideoSink()
// We need a native window ID to use the GstVideoOverlay interface.
// Bail out if the Qt platform plugin in use cannot provide a sensible WId.
- if (platform != QLatin1String("xcb"))
+ if (platform != QLatin1String("xcb") && platform != QLatin1String("wayland"))
return {};
QGstElement choice;
@@ -291,7 +142,6 @@ QGstreamerVideoOverlay::QGstreamerVideoOverlay(QObject *parent, const QByteArray
QGstreamerVideoOverlay::~QGstreamerVideoOverlay()
{
if (!m_videoSink.isNull()) {
- delete m_sinkProperties;
QGstPad pad = m_videoSink.staticPad("sink");
removeProbeFromPad(pad.pad());
}
@@ -312,10 +162,9 @@ void QGstreamerVideoOverlay::setVideoSink(QGstElement sink)
QGstPad pad = m_videoSink.staticPad("sink");
addProbeToPad(pad.pad());
- QByteArray sinkName(sink.name());
- bool isVaapi = sinkName.startsWith("vaapisink");
- delete m_sinkProperties;
- m_sinkProperties = isVaapi ? new QVaapiSinkProperties(sink) : new QXVImageSinkProperties(sink);
+ auto *klass = G_OBJECT_GET_CLASS(m_videoSink.object());
+ m_hasForceAspectRatio = g_object_class_find_property(klass, "force-aspect-ratio");
+ m_hasFullscreen = g_object_class_find_property(klass, "fullscreen");
}
QSize QGstreamerVideoOverlay::nativeVideoSize() const
@@ -331,7 +180,9 @@ void QGstreamerVideoOverlay::setWindowHandle(WId id)
applyRenderRect();
// Properties need to be reset when changing the winId.
- m_sinkProperties->reset();
+ setAspectRatioMode(m_aspectRatioMode);
+ setFullScreen(m_fullScreen);
+ applyRenderRect();
}
}
@@ -356,6 +207,11 @@ void QGstreamerVideoOverlay::applyRenderRect()
y = renderRect.y();
w = renderRect.width();
h = renderRect.height();
+ QSize scaledVideo = m_nativeVideoSize.scaled(w, h, m_aspectRatioMode);
+ x += (w - scaledVideo.width())/2;
+ y += (h - scaledVideo.height())/2;
+ w = scaledVideo.width();
+ h = scaledVideo.height();
}
if (!m_videoSink.isNull() && GST_IS_VIDEO_OVERLAY(m_videoSink.object()))
@@ -368,32 +224,22 @@ void QGstreamerVideoOverlay::probeCaps(GstCaps *caps)
if (size != m_nativeVideoSize) {
m_nativeVideoSize = size;
emit nativeVideoSizeChanged();
+ applyRenderRect();
}
}
void QGstreamerVideoOverlay::setAspectRatioMode(Qt::AspectRatioMode mode)
{
- m_sinkProperties->setAspectRatioMode(mode);
-}
-
-void QGstreamerVideoOverlay::setBrightness(float brightness)
-{
- m_sinkProperties->setBrightness(brightness);
-}
-
-void QGstreamerVideoOverlay::setContrast(float contrast)
-{
- m_sinkProperties->setContrast(contrast);
-}
-
-void QGstreamerVideoOverlay::setHue(float hue)
-{
- m_sinkProperties->setHue(hue);
+ m_aspectRatioMode = mode;
+ if (m_hasForceAspectRatio)
+ m_videoSink.set("force-aspect-ratio", (mode == Qt::KeepAspectRatio));
}
-void QGstreamerVideoOverlay::setSaturation(float saturation)
+void QGstreamerVideoOverlay::setFullScreen(bool fullscreen)
{
- m_sinkProperties->setSaturation(saturation);
+ m_fullScreen = fullscreen;
+ if (m_hasFullscreen)
+ m_videoSink.set("fullscreen", fullscreen);
}
bool QGstreamerVideoOverlay::processSyncMessage(const QGstreamerMessage &message)
diff --git a/src/multimedia/platform/gstreamer/common/qgstreamervideooverlay_p.h b/src/multimedia/platform/gstreamer/common/qgstreamervideooverlay_p.h
index c374edbe9..bdc97e279 100644
--- a/src/multimedia/platform/gstreamer/common/qgstreamervideooverlay_p.h
+++ b/src/multimedia/platform/gstreamer/common/qgstreamervideooverlay_p.h
@@ -76,13 +76,8 @@ public:
void setWindowHandle(WId id);
void setRenderRectangle(const QRect &rect);
- Qt::AspectRatioMode aspectRatioMode() const;
void setAspectRatioMode(Qt::AspectRatioMode mode);
-
- void setBrightness(float brightness);
- void setContrast(float contrast);
- void setHue(float hue);
- void setSaturation(float saturation);
+ void setFullScreen(bool fullscreen);
bool processSyncMessage(const QGstreamerMessage &message) override;
@@ -99,7 +94,11 @@ private:
QGstElement m_videoSink;
QSize m_nativeVideoSize;
- QGstreamerSinkProperties *m_sinkProperties = nullptr;
+ bool m_hasForceAspectRatio = false;
+ bool m_hasFullscreen = false;
+ Qt::AspectRatioMode m_aspectRatioMode = Qt::KeepAspectRatio;
+ bool m_fullScreen = false;
+
WId m_windowId = 0;
QRect renderRect;
};
diff --git a/src/multimedia/platform/gstreamer/common/qgstreamervideosink.cpp b/src/multimedia/platform/gstreamer/common/qgstreamervideosink.cpp
index 443d6b40d..17aeec957 100644
--- a/src/multimedia/platform/gstreamer/common/qgstreamervideosink.cpp
+++ b/src/multimedia/platform/gstreamer/common/qgstreamervideosink.cpp
@@ -123,26 +123,6 @@ void QGstreamerVideoSink::setAspectRatioMode(Qt::AspectRatioMode mode)
m_videoOverlay->setAspectRatioMode(mode);
}
-void QGstreamerVideoSink::setBrightness(float brightness)
-{
- m_videoOverlay->setBrightness(brightness);
-}
-
-void QGstreamerVideoSink::setContrast(float contrast)
-{
- m_videoOverlay->setContrast(contrast);
-}
-
-void QGstreamerVideoSink::setHue(float hue)
-{
- m_videoOverlay->setHue(hue);
-}
-
-void QGstreamerVideoSink::setSaturation(float saturation)
-{
- m_videoOverlay->setSaturation(saturation);
-}
-
void QGstreamerVideoSink::setFullScreen(bool fullScreen)
{
if (fullScreen == m_fullScreen)
@@ -150,6 +130,7 @@ void QGstreamerVideoSink::setFullScreen(bool fullScreen)
m_fullScreen = fullScreen;
if (!m_windowId)
updateSinkElement();
+ m_videoOverlay->setFullScreen(fullScreen);
}
QSize QGstreamerVideoSink::nativeSize() const
diff --git a/src/multimedia/platform/gstreamer/common/qgstreamervideosink_p.h b/src/multimedia/platform/gstreamer/common/qgstreamervideosink_p.h
index 3df73eccb..2f40dab77 100644
--- a/src/multimedia/platform/gstreamer/common/qgstreamervideosink_p.h
+++ b/src/multimedia/platform/gstreamer/common/qgstreamervideosink_p.h
@@ -82,11 +82,6 @@ public:
void setAspectRatioMode(Qt::AspectRatioMode mode) override;
- void setBrightness(float brightness) override;
- void setContrast(float contrast) override;
- void setHue(float hue) override;
- void setSaturation(float saturation) override;
-
QGstElement gstSink();
bool isReady() const { return m_windowId != 0; }
diff --git a/src/multimediawidgets/qvideowidget.cpp b/src/multimediawidgets/qvideowidget.cpp
index 659c83ece..fa54d7874 100644
--- a/src/multimediawidgets/qvideowidget.cpp
+++ b/src/multimediawidgets/qvideowidget.cpp
@@ -64,13 +64,6 @@ using namespace Qt;
QT_BEGIN_NAMESPACE
-
-void QVideoWidgetPrivate::_q_dimensionsChanged()
-{
- q_func()->updateGeometry();
- q_func()->update();
-}
-
void QVideoWidgetPrivate::_q_newFrame(const QVideoFrame &frame)
{
lastFrame = frame;
@@ -189,120 +182,6 @@ void QVideoWidget::setFullScreen(bool fullScreen)
\sa isFullScreen()
*/
-#if 0
-/*!
- \property QVideoWidget::brightness
- \brief an adjustment to the brightness of displayed video.
-
- Valid brightness values range between -1. and 1., the default is 0.
-*/
-
-float QVideoWidget::brightness() const
-{
- return d_func()->videoSink->brightness();
-}
-
-void QVideoWidget::setBrightness(float brightness)
-{
- Q_D(QVideoWidget);
- d->videoSink->setBrightness(brightness);
- float boundedBrightness = qBound(-1., brightness, 1.);
-
- if (boundedBrightness == d->videoSink->brightness())
- return;
-
- d->videoSink->setBrightness(boundedBrightness);
- emit brightnessChanged(boundedBrightness);
-}
-
-/*!
- \fn QVideoWidget::brightnessChanged(float brightness)
-
- Signals that a video widgets's \a brightness adjustment has changed.
-
- \sa brightness()
-*/
-
-/*!
- \property QVideoWidget::contrast
- \brief an adjustment to the contrast of displayed video.
-
- Valid contrast values range between -1. and 1., the default is 0.
-
-*/
-
-float QVideoWidget::contrast() const
-{
- return d_func()->videoSink->contrast();
-}
-
-void QVideoWidget::setContrast(float contrast)
-{
- Q_D(QVideoWidget);
- d->videoSink->setContrast(contrast);
-}
-
-/*!
- \fn QVideoWidget::contrastChanged(float contrast)
-
- Signals that a video widgets's \a contrast adjustment has changed.
-
- \sa contrast()
-*/
-
-/*!
- \property QVideoWidget::hue
- \brief an adjustment to the hue of displayed video.
-
- Valid hue values range between -1. and 1., the default is 0.
-*/
-
-float QVideoWidget::hue() const
-{
- return d_func()->videoSink->hue();
-}
-
-void QVideoWidget::setHue(float hue)
-{
- Q_D(QVideoWidget);
- d->videoSink->setHue(hue);
-}
-
-/*!
- \fn QVideoWidget::hueChanged(float hue)
-
- Signals that a video widgets's \a hue has changed.
-
- \sa hue()
-*/
-
-/*!
- \property QVideoWidget::saturation
- \brief an adjustment to the saturation of displayed video.
-
- Valid saturation values range between -1. and 1., the default is 0.
-*/
-
-float QVideoWidget::saturation() const
-{
- return d_func()->videoSink->saturation();
-}
-
-void QVideoWidget::setSaturation(float saturation)
-{
- Q_D(QVideoWidget);
- d->videoSink->setSaturation(saturation);
-}
-
-/*!
- \fn QVideoWidget::saturationChanged(float saturation)
-
- Signals that a video widgets's \a saturation has changed.
-
- \sa saturation()
-*/
-#endif
-
/*!
Returns the size hint for the current back end,
if there is one, or else the size hint from QWidget.
@@ -362,7 +241,6 @@ void QVideoWidget::showEvent(QShowEvent *event)
*/
void QVideoWidget::hideEvent(QHideEvent *event)
{
- // ### maybe suspend video decoding???
QWidget::hideEvent(event);
}
diff --git a/src/multimediawidgets/qvideowidget.h b/src/multimediawidgets/qvideowidget.h
index 57c132b9b..8ccc93ad7 100644
--- a/src/multimediawidgets/qvideowidget.h
+++ b/src/multimediawidgets/qvideowidget.h
@@ -91,7 +91,6 @@ protected:
private:
Q_DECLARE_PRIVATE(QVideoWidget)
- Q_PRIVATE_SLOT(d_func(), void _q_dimensionsChanged())
Q_PRIVATE_SLOT(d_func(), void _q_newFrame(const QVideoFrame &))
};
diff --git a/src/multimediawidgets/qvideowidget_p.h b/src/multimediawidgets/qvideowidget_p.h
index e425ff315..1b82ea574 100644
--- a/src/multimediawidgets/qvideowidget_p.h
+++ b/src/multimediawidgets/qvideowidget_p.h
@@ -70,15 +70,10 @@ public:
QVideoFrame lastFrame;
QVideoSink *videoSink = nullptr;
+ QRect targetRect;
bool createBackend();
- void _q_brightnessChanged(int brightness);
- void _q_contrastChanged(int contrast);
- void _q_hueChanged(int hue);
- void _q_saturationChanged(int saturation);
- void _q_fullScreenChanged(bool fullScreen);
- void _q_dimensionsChanged();
void _q_newFrame(const QVideoFrame &frame);
};