From e0a069edc2d79b69fd187ffbe03a8388a612b3ff Mon Sep 17 00:00:00 2001 From: Jesus Fernandez Date: Mon, 19 Mar 2018 12:05:57 +0100 Subject: Remove unreachable code Actions intended to be performed by the unreachable code will never occur. In CameraBinLocks::lockStatus(QCamera::LockType): Code block is unreachable because of the syntactic structure of the code (CWE-561) Coverity-Id: 188406 Change-Id: I55a7ef8e87673519ff4f1ad5677054b34bf66d17 Reviewed-by: Christian Stromme --- src/plugins/gstreamer/camerabin/camerabinlocks.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/plugins/gstreamer/camerabin/camerabinlocks.cpp b/src/plugins/gstreamer/camerabin/camerabinlocks.cpp index 2ccc1b0bc..89be2ac5d 100644 --- a/src/plugins/gstreamer/camerabin/camerabinlocks.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinlocks.cpp @@ -102,8 +102,6 @@ QCamera::LockStatus CameraBinLocks::lockStatus(QCamera::LockType lock) const default: return QCamera::Unlocked; } - - return lock == QCamera::LockFocus ? m_focus->focusStatus() : QCamera::Unlocked; } void CameraBinLocks::searchAndLock(QCamera::LockTypes locks) -- cgit v1.2.3 From 204b623a8cfe2b2c9fb95fcf7b71fe0f183a5302 Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Wed, 15 Nov 2017 09:31:09 +0100 Subject: Add test for checking error handling on start If a camera is not started successfully error() signal has to be emitted. This change adds a test for checking that we emit and set the correct status and state when trying to start an already active camera. Task-number: QTBUG-51825 Change-Id: Ia14119aa9a93a76e363214401b8c2e9f216e35c9 Reviewed-by: Christian Stromme --- .../qcamerabackend/tst_qcamerabackend.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp b/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp index 5035cb6b1..b568f38fc 100644 --- a/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp +++ b/tests/auto/integration/qcamerabackend/tst_qcamerabackend.cpp @@ -76,6 +76,7 @@ private slots: void testCtorWithPosition(); void testCameraStates(); + void testCameraStartError(); void testCaptureMode(); void testCameraCapture(); void testCaptureToBuffer(); @@ -251,6 +252,27 @@ void tst_QCameraBackend::testCameraStates() QCOMPARE(errorSignal.count(), 0); } +void tst_QCameraBackend::testCameraStartError() +{ + QCamera camera1(QCameraInfo::defaultCamera()); + QCamera camera2(QCameraInfo::defaultCamera()); + QSignalSpy errorSpy1(&camera1, QOverload::of(&QCamera::error)); + QSignalSpy errorSpy2(&camera2, QOverload::of(&QCamera::error)); + + camera1.start(); + camera2.start(); + + QCOMPARE(camera1.state(), QCamera::ActiveState); + QTRY_COMPARE(camera1.status(), QCamera::ActiveStatus); + QCOMPARE(camera1.error(), QCamera::NoError); + QCOMPARE(camera2.state(), QCamera::UnloadedState); + QCOMPARE(camera2.status(), QCamera::UnloadedStatus); + QCOMPARE(camera2.error(), QCamera::CameraError); + + QCOMPARE(errorSpy1.count(), 0); + QCOMPARE(errorSpy2.count(), 1); +} + void tst_QCameraBackend::testCaptureMode() { QCamera camera; -- cgit v1.2.3 From 485cb9cec54ee3b9466e730037e7480296e2ecd0 Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Tue, 14 Nov 2017 13:47:09 +0100 Subject: DirectShow: Emit an error if QCamera::start() fails If a camera is not started successfully, then an error() should be emitted. After an error the camera's state will be QCamera::UnloadedState and status will be QCamera::UnloadedStatus. The error signal is handled when the camera is unable to set following states: QCamera::UnloadedState, QCamera::LoadedState or QCamera::LoadingState. Thus additionally to QCamera::start() an error can be emitted even when QCamera::load(), QCamera::unload(), or QCamera::stop() is called. Task-number: QTBUG-51825 Change-Id: Ib5ea08ed7983ea49a7bf8c0321cc5266a68d9144 Reviewed-by: Christian Stromme --- src/plugins/directshow/camera/dscameracontrol.cpp | 2 ++ src/plugins/directshow/camera/dscamerasession.cpp | 38 +++++++++++++++-------- src/plugins/directshow/camera/dscamerasession.h | 2 ++ 3 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/plugins/directshow/camera/dscameracontrol.cpp b/src/plugins/directshow/camera/dscameracontrol.cpp index a6824976d..8d923da9f 100644 --- a/src/plugins/directshow/camera/dscameracontrol.cpp +++ b/src/plugins/directshow/camera/dscameracontrol.cpp @@ -53,6 +53,8 @@ DSCameraControl::DSCameraControl(QObject *parent) m_session = qobject_cast(parent); connect(m_session, SIGNAL(statusChanged(QCamera::Status)), this, SIGNAL(statusChanged(QCamera::Status))); + connect(m_session, &DSCameraSession::cameraError, + this, &DSCameraControl::error); } DSCameraControl::~DSCameraControl() diff --git a/src/plugins/directshow/camera/dscamerasession.cpp b/src/plugins/directshow/camera/dscamerasession.cpp index 9b642872a..ca3c47cb8 100644 --- a/src/plugins/directshow/camera/dscamerasession.cpp +++ b/src/plugins/directshow/camera/dscamerasession.cpp @@ -441,30 +441,33 @@ bool DSCameraSession::startPreview() setStatus(QCamera::StartingStatus); + QString errorString; HRESULT hr = S_OK; IMediaControl* pControl = 0; if (!configurePreviewFormat()) { - qWarning() << "Failed to configure preview format"; + errorString = tr("Failed to configure preview format"); goto failed; } - if (!connectGraph()) + if (!connectGraph()) { + errorString = tr("Failed to connect graph"); goto failed; + } if (m_surface) m_surface->start(m_previewSurfaceFormat); hr = m_filterGraph->QueryInterface(IID_IMediaControl, (void**)&pControl); if (FAILED(hr)) { - qWarning() << "failed to get stream control"; + errorString = tr("Failed to get stream control"); goto failed; } hr = pControl->Run(); pControl->Release(); if (FAILED(hr)) { - qWarning() << "failed to start"; + errorString = tr("Failed to start"); goto failed; } @@ -477,7 +480,7 @@ failed: if (m_surface && m_surface->isActive()) m_surface->stop(); disconnectGraph(); - setStatus(QCamera::LoadedStatus); + setError(QCamera::CameraError, errorString); return false; } @@ -491,17 +494,18 @@ bool DSCameraSession::stopPreview() if (m_previewSampleGrabber) m_previewSampleGrabber->stop(); + QString errorString; IMediaControl* pControl = 0; HRESULT hr = m_filterGraph->QueryInterface(IID_IMediaControl, (void**)&pControl); if (FAILED(hr)) { - qWarning() << "failed to get stream control"; + errorString = tr("Failed to get stream control"); goto failed; } hr = pControl->Stop(); pControl->Release(); if (FAILED(hr)) { - qWarning() << "failed to stop"; + errorString = tr("Failed to stop"); goto failed; } @@ -514,10 +518,16 @@ bool DSCameraSession::stopPreview() return true; failed: - setStatus(QCamera::ActiveStatus); + setError(QCamera::CameraError, errorString); return false; } +void DSCameraSession::setError(int error, const QString &errorString) +{ + emit cameraError(error, errorString); + setStatus(QCamera::UnloadedStatus); +} + void DSCameraSession::setStatus(QCamera::Status status) { if (m_status == status) @@ -668,6 +678,7 @@ bool DSCameraSession::createFilterGraph() // Previously containered in . static const CLSID cLSID_NullRenderer = { 0xC1F400A4, 0x3F08, 0x11d3, { 0x9F, 0x0B, 0x00, 0x60, 0x08, 0x03, 0x9E, 0x37 } }; + QString errorString; HRESULT hr; IMoniker* pMoniker = NULL; ICreateDevEnum* pDevEnum = NULL; @@ -677,7 +688,7 @@ bool DSCameraSession::createFilterGraph() hr = CoCreateInstance(CLSID_FilterGraph,NULL,CLSCTX_INPROC, IID_IGraphBuilder, (void**)&m_filterGraph); if (FAILED(hr)) { - qWarning() << "failed to create filter graph"; + errorString = tr("Failed to create filter graph"); goto failed; } @@ -685,14 +696,14 @@ bool DSCameraSession::createFilterGraph() hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, NULL, CLSCTX_INPROC, IID_ICaptureGraphBuilder2, (void**)&m_graphBuilder); if (FAILED(hr)) { - qWarning() << "failed to create graph builder"; + errorString = tr("Failed to create graph builder"); goto failed; } // Attach the filter graph to the capture graph hr = m_graphBuilder->SetFiltergraph(m_filterGraph); if (FAILED(hr)) { - qWarning() << "failed to connect capture graph and filter graph"; + errorString = tr("Failed to connect capture graph and filter graph"); goto failed; } @@ -762,7 +773,7 @@ bool DSCameraSession::createFilterGraph() } if (!m_sourceFilter) { - qWarning() << "No capture device found"; + errorString = tr("No capture device found"); goto failed; } @@ -779,7 +790,7 @@ bool DSCameraSession::createFilterGraph() hr = CoCreateInstance(cLSID_NullRenderer, NULL, CLSCTX_INPROC, IID_IBaseFilter, (void**)&m_nullRendererFilter); if (FAILED(hr)) { - qWarning() << "failed to create null renderer"; + errorString = tr("Failed to create null renderer"); goto failed; } @@ -793,6 +804,7 @@ failed: SAFE_RELEASE(m_nullRendererFilter); SAFE_RELEASE(m_filterGraph); SAFE_RELEASE(m_graphBuilder); + setError(QCamera::CameraError, errorString); return false; } diff --git a/src/plugins/directshow/camera/dscamerasession.h b/src/plugins/directshow/camera/dscamerasession.h index e28015534..07c3d9ef9 100644 --- a/src/plugins/directshow/camera/dscamerasession.h +++ b/src/plugins/directshow/camera/dscamerasession.h @@ -138,6 +138,7 @@ Q_SIGNALS: void readyForCaptureChanged(bool); void captureError(int id, int error, const QString &errorString); void captureDestinationChanged(QCameraImageCapture::CaptureDestinations); + void cameraError(int error, const QString &errorString); private Q_SLOTS: void presentFrame(); @@ -176,6 +177,7 @@ private: void updateSourceCapabilities(); bool configurePreviewFormat(); void updateImageProcessingParametersInfos(); + void setError(int error, const QString &errorString); // These static functions are used for scaling of adjustable parameters, // which have the ranges from -1.0 to +1.0 in the QCameraImageProcessing API. -- cgit v1.2.3 From d49abfda2f5bbf15de3a5133c77d5115a75b3c2b Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Wed, 15 Nov 2017 09:40:29 +0100 Subject: Gstreamer: Emit an error if QCamera::start() fails If a camera is not started successfully error() signal has to be emitted. Added emitting an error from video source. Emitted only first error to prevent multiple subsequent errors. Added debug message. Task-number: QTBUG-51825 Change-Id: I6ac936d2728213a4a64f3e4eb25ae2e2f109acca Reviewed-by: Christian Stromme --- src/plugins/gstreamer/camerabin/camerabinsession.cpp | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.cpp b/src/plugins/gstreamer/camerabin/camerabinsession.cpp index 39f97e989..3bb6ebffb 100644 --- a/src/plugins/gstreamer/camerabin/camerabinsession.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinsession.cpp @@ -767,7 +767,11 @@ void CameraBinSession::setStateHelper(QCamera::State state) void CameraBinSession::setError(int err, const QString &errorString) { - m_pendingState = QCamera::UnloadedState; + // Emit only first error + if (m_pendingState == QCamera::UnloadedState) + return; + + setState(QCamera::UnloadedState); emit error(err, errorString); setStatus(QCamera::UnloadedStatus); } @@ -990,10 +994,14 @@ bool CameraBinSession::processBusMessage(const QGstreamerMessage &message) if (err && err->message) { message = QString::fromUtf8(err->message); qWarning() << "CameraBin error:" << message; +#if CAMERABIN_DEBUG + qWarning() << QString::fromUtf8(debug); +#endif } - //only report error messager from camerabin - if (GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_camerabin)) { + // Only report error messages from camerabin or video source + if (GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_camerabin) + || GST_MESSAGE_SRC(gm) == GST_OBJECT_CAST(m_videoSrc)) { if (message.isEmpty()) message = tr("Camera error"); -- cgit v1.2.3 From 2831fb0e5035f248988fce12e76ff55495212497 Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Fri, 15 Dec 2017 14:23:06 +0100 Subject: Audiocapture: Fix setting QAudioEncoderSettings::bitRate The sample size is now correctly calculated using provided bit rate via QAudioEncoderSettings. The bit rate is calculated like bitrate = sample size * sample rate * channel count Fixed bug when sample size is 8 when bit rate and sample rate is 8000 which is not correct. The bit rate must be 8 * 8000. Task-number: QTBUG-65207 Change-Id: I660fadfaaf6cc63004480fb84165252360b7f75e Reviewed-by: Christian Stromme --- src/plugins/audiocapture/audioencodercontrol.cpp | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/plugins/audiocapture/audioencodercontrol.cpp b/src/plugins/audiocapture/audioencodercontrol.cpp index d8a83bf26..6fc519cef 100644 --- a/src/plugins/audiocapture/audioencodercontrol.cpp +++ b/src/plugins/audiocapture/audioencodercontrol.cpp @@ -54,13 +54,12 @@ static QAudioFormat audioSettingsToAudioFormat(const QAudioEncoderSettings &sett fmt.setCodec(settings.codec()); fmt.setChannelCount(settings.channelCount()); fmt.setSampleRate(settings.sampleRate()); - if (settings.sampleRate() == 8000 && settings.bitRate() == 8000) { - fmt.setSampleType(QAudioFormat::UnSignedInt); - fmt.setSampleSize(8); - } else { - fmt.setSampleSize(16); - fmt.setSampleType(QAudioFormat::SignedInt); - } + int sampleSize = 16; + if (settings.bitRate() && settings.channelCount() && settings.sampleRate()) + sampleSize = settings.bitRate() / settings.channelCount() / settings.sampleRate(); + fmt.setSampleSize(sampleSize); + fmt.setSampleType(sampleSize == 8 ? QAudioFormat::UnSignedInt : QAudioFormat::SignedInt); + fmt.setByteOrder(QAudioDeviceInfo::defaultInputDevice().preferredFormat().byteOrder()); return fmt; } -- cgit v1.2.3 From 5b99ac4403933ed20bd4ccd9c2c931be0a677331 Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Fri, 26 Jan 2018 09:04:30 +0100 Subject: Allow to receive mouse move events in QVideoWidget No move events are being received for QVideoWidget even with enabled Qt::WA_MouseTracking. All these events are ignored because video widget from QVideoWidgetControl always has disabled Qt::WA_MouseTracking. Proxied this mouse tracking property to video widget. Task-number: QTBUG-30728 Change-Id: Ic196042596906ce8b5674b62ea66f5e035ba3cfe Reviewed-by: Christian Stromme --- src/multimediawidgets/qvideowidget.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/multimediawidgets/qvideowidget.cpp b/src/multimediawidgets/qvideowidget.cpp index 9a01c73aa..a0161c17f 100644 --- a/src/multimediawidgets/qvideowidget.cpp +++ b/src/multimediawidgets/qvideowidget.cpp @@ -76,7 +76,9 @@ QVideoWidgetControlBackend::QVideoWidgetControlBackend( layout->setMargin(0); layout->setSpacing(0); - layout->addWidget(control->videoWidget()); + QWidget *videoWidget = control->videoWidget(); + videoWidget->setMouseTracking(widget->hasMouseTracking()); + layout->addWidget(videoWidget); widget->setLayout(layout); } -- cgit v1.2.3 From 44b3628c1bbcf36655b8d62fcd082f6db5d92f9a Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Tue, 6 Feb 2018 09:05:28 +0100 Subject: Gstreamer: Fix setting vaapi sink properties Since vaapi and xvimage sinks require different ranges for the properties: brightness, contrast, hue, saturation. Added support of vaapi ranges. It also fixes problem when contrast was always 0 as default value which led to always show black screen. - brightness xvimage: Allowed values: [-1000,1000], Default value: 0 vaapi: Allowed values: [-1,1], Default value: 0 - contrast xvimage: Allowed values: [-1000,1000], Default value: 0 vaapi: Allowed values: [0,2], Default value: 1 - hue xvimage: Allowed values: [-1000,1000], Default value: 0 vaapi: Allowed values: [-180,180], Default value: 0 - saturation xvimage: Allowed values: [-1000,1000], Default value: 0 vaapi: Allowed values: [0,2], Default value: 1 Task-number: QTBUG-23761 Change-Id: I8fda8ce4c6f47c4567e67c670f802a0e9f55af6e Reviewed-by: Christian Stromme --- src/gsttools/qgstreamervideooverlay.cpp | 395 +++++++++++++++------ .../gsttools_headers/qgstreamervideooverlay_p.h | 23 +- 2 files changed, 294 insertions(+), 124 deletions(-) diff --git a/src/gsttools/qgstreamervideooverlay.cpp b/src/gsttools/qgstreamervideooverlay.cpp index 6ad70fd6a..de4f255d5 100644 --- a/src/gsttools/qgstreamervideooverlay.cpp +++ b/src/gsttools/qgstreamervideooverlay.cpp @@ -64,59 +64,258 @@ static const ElementMap elementMap[] = { "xcb", "ximagesink" } }; -QGstreamerVideoOverlay::QGstreamerVideoOverlay(QObject *parent, const QByteArray &elementName) - : QObject(parent) - , QGstreamerBufferProbe(QGstreamerBufferProbe::ProbeCaps) - , m_videoSink(0) - , m_isActive(false) - , m_hasForceAspectRatio(false) - , m_hasBrightness(false) - , m_hasContrast(false) - , m_hasHue(false) - , m_hasSaturation(false) - , m_hasShowPrerollFrame(false) - , m_windowId(0) - , m_aspectRatioMode(Qt::KeepAspectRatio) - , m_brightness(0) - , m_contrast(0) - , m_hue(0) - , m_saturation(0) +class QGstreamerSinkProperties { - if (!elementName.isEmpty()) - m_videoSink = gst_element_factory_make(elementName.constData(), NULL); - else - m_videoSink = findBestVideoSink(); - - if (m_videoSink) { - qt_gst_object_ref_sink(GST_OBJECT(m_videoSink)); //Take ownership +public: + virtual ~QGstreamerSinkProperties() + { + } - GstPad *pad = gst_element_get_static_pad(m_videoSink, "sink"); - addProbeToPad(pad); - gst_object_unref(GST_OBJECT(pad)); + virtual bool hasShowPrerollFrame() const = 0; + virtual void reset() = 0; + virtual int brightness() const = 0; + virtual bool setBrightness(int brightness) = 0; + virtual int contrast() const = 0; + virtual bool setContrast(int contrast) = 0; + virtual int hue() const = 0; + virtual bool setHue(int hue) = 0; + virtual int saturation() const = 0; + virtual bool setSaturation(int saturation) = 0; + virtual Qt::AspectRatioMode aspectRatioMode() const = 0; + virtual void setAspectRatioMode(Qt::AspectRatioMode mode) = 0; +}; +class QXVImageSinkProperties : public QGstreamerSinkProperties +{ +public: + QXVImageSinkProperties(GstElement *sink) + : m_videoSink(sink) + { m_hasForceAspectRatio = g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "force-aspect-ratio"); m_hasBrightness = g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "brightness"); m_hasContrast = g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "contrast"); m_hasHue = g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "hue"); m_hasSaturation = g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "saturation"); m_hasShowPrerollFrame = g_object_class_find_property(G_OBJECT_GET_CLASS(m_videoSink), "show-preroll-frame"); + } - if (m_hasShowPrerollFrame) { - g_signal_connect(m_videoSink, "notify::show-preroll-frame", - G_CALLBACK(showPrerollFrameChanged), this); + bool hasShowPrerollFrame() const override + { + return m_hasShowPrerollFrame; + } + + void reset() override + { + setAspectRatioMode(m_aspectRatioMode); + setBrightness(m_brightness); + setContrast(m_contrast); + setHue(m_hue); + setSaturation(m_saturation); + } + + int brightness() const override + { + int brightness = 0; + if (m_hasBrightness) + g_object_get(G_OBJECT(m_videoSink), "brightness", &brightness, NULL); + + return brightness / 10; + } + + bool setBrightness(int brightness) override + { + m_brightness = brightness; + if (m_hasBrightness) + g_object_set(G_OBJECT(m_videoSink), "brightness", brightness * 10, NULL); + + return m_hasBrightness; + } + + int contrast() const override + { + int contrast = 0; + if (m_hasContrast) + g_object_get(G_OBJECT(m_videoSink), "contrast", &contrast, NULL); + + return contrast / 10; + } + + bool setContrast(int contrast) override + { + m_contrast = contrast; + if (m_hasContrast) + g_object_set(G_OBJECT(m_videoSink), "contrast", contrast * 10, NULL); + + return m_hasContrast; + } + + int hue() const override + { + int hue = 0; + if (m_hasHue) + g_object_get(G_OBJECT(m_videoSink), "hue", &hue, NULL); + + return hue / 10; + } + + bool setHue(int hue) override + { + m_hue = hue; + if (m_hasHue) + g_object_set(G_OBJECT(m_videoSink), "hue", hue * 10, NULL); + + return m_hasHue; + } + + int saturation() const override + { + int saturation = 0; + if (m_hasSaturation) + g_object_get(G_OBJECT(m_videoSink), "saturation", &saturation, NULL); + + return saturation / 10; + } + + bool setSaturation(int saturation) override + { + m_saturation = saturation; + if (m_hasSaturation) + g_object_set(G_OBJECT(m_videoSink), "saturation", saturation * 10, NULL); + + return m_hasSaturation; + } + + Qt::AspectRatioMode aspectRatioMode() const override + { + Qt::AspectRatioMode mode = Qt::KeepAspectRatio; + if (m_hasForceAspectRatio) { + gboolean forceAR = false; + g_object_get(G_OBJECT(m_videoSink), "force-aspect-ratio", &forceAR, NULL); + if (!forceAR) + mode = Qt::IgnoreAspectRatio; } + + return mode; } -} -QGstreamerVideoOverlay::~QGstreamerVideoOverlay() + void setAspectRatioMode(Qt::AspectRatioMode mode) override + { + m_aspectRatioMode = mode; + if (m_hasForceAspectRatio) { + g_object_set(G_OBJECT(m_videoSink), + "force-aspect-ratio", + (mode == Qt::KeepAspectRatio), + (const char*)NULL); + } + } + +protected: + + GstElement *m_videoSink = nullptr; + bool m_hasForceAspectRatio = false; + bool m_hasBrightness = false; + bool m_hasContrast = false; + bool m_hasHue = false; + bool m_hasSaturation = false; + bool m_hasShowPrerollFrame = false; + Qt::AspectRatioMode m_aspectRatioMode = Qt::KeepAspectRatio; + int m_brightness = 0; + int m_contrast = 0; + int m_hue = 0; + int m_saturation = 0; +}; + +class QVaapiSinkProperties : public QXVImageSinkProperties { - if (m_videoSink) { - GstPad *pad = gst_element_get_static_pad(m_videoSink, "sink"); - removeProbeFromPad(pad); - gst_object_unref(GST_OBJECT(pad)); - gst_object_unref(GST_OBJECT(m_videoSink)); +public: + QVaapiSinkProperties(GstElement *sink) + : QXVImageSinkProperties(sink) + { + // Set default values. + m_contrast = 1; + m_saturation = 1; + } + + int brightness() const override + { + gfloat brightness = 0; + if (m_hasBrightness) + g_object_get(G_OBJECT(m_videoSink), "brightness", &brightness, NULL); + + return brightness * 100; // [-1,1] -> [-100,100] + } + + bool setBrightness(int brightness) override + { + m_brightness = brightness; + if (m_hasBrightness) { + gfloat v = brightness / 100.0; // [-100,100] -> [-1,1] + g_object_set(G_OBJECT(m_videoSink), "brightness", v, NULL); + } + + return m_hasBrightness; + } + + int contrast() const override + { + gfloat contrast = 1; + if (m_hasContrast) + g_object_get(G_OBJECT(m_videoSink), "contrast", &contrast, NULL); + + return (contrast - 1) * 100; // [0,2] -> [-100,100] + } + + bool setContrast(int contrast) override + { + m_contrast = contrast; + if (m_hasContrast) { + gfloat v = (contrast / 100.0) + 1; // [-100,100] -> [0,2] + g_object_set(G_OBJECT(m_videoSink), "contrast", v, NULL); + } + + return m_hasContrast; + } + + int hue() const override + { + gfloat hue = 0; + if (m_hasHue) + g_object_get(G_OBJECT(m_videoSink), "hue", &hue, NULL); + + return hue / 180 * 100; // [-180,180] -> [-100,100] + } + + bool setHue(int hue) override + { + m_hue = hue; + if (m_hasHue) { + gfloat v = hue / 100.0 * 180; // [-100,100] -> [-180,180] + g_object_set(G_OBJECT(m_videoSink), "hue", v, NULL); + } + + return m_hasHue; } -} + + int saturation() const override + { + gfloat saturation = 1; + if (m_hasSaturation) + g_object_get(G_OBJECT(m_videoSink), "saturation", &saturation, NULL); + + return (saturation - 1) * 100; // [0,2] -> [-100,100] + } + + bool setSaturation(int saturation) override + { + m_saturation = saturation; + if (m_hasSaturation) { + gfloat v = (saturation / 100.0) + 1; // [-100,100] -> [0,2] + g_object_set(G_OBJECT(m_videoSink), "saturation", v, NULL); + } + + return m_hasSaturation; + } +}; static bool qt_gst_element_is_functioning(GstElement *element) { @@ -129,7 +328,7 @@ static bool qt_gst_element_is_functioning(GstElement *element) return false; } -GstElement *QGstreamerVideoOverlay::findBestVideoSink() const +static GstElement *findBestVideoSink() { GstElement *choice = 0; QString platform = QGuiApplication::platformName(); @@ -176,6 +375,44 @@ GstElement *QGstreamerVideoOverlay::findBestVideoSink() const return choice; } +QGstreamerVideoOverlay::QGstreamerVideoOverlay(QObject *parent, const QByteArray &elementName) + : QObject(parent) + , QGstreamerBufferProbe(QGstreamerBufferProbe::ProbeCaps) +{ + if (!elementName.isEmpty()) + m_videoSink = gst_element_factory_make(elementName.constData(), NULL); + else + m_videoSink = findBestVideoSink(); + + if (m_videoSink) { + qt_gst_object_ref_sink(GST_OBJECT(m_videoSink)); //Take ownership + + GstPad *pad = gst_element_get_static_pad(m_videoSink, "sink"); + addProbeToPad(pad); + gst_object_unref(GST_OBJECT(pad)); + + QString sinkName(QLatin1String(GST_OBJECT_NAME(m_videoSink))); + bool isVaapi = sinkName.startsWith(QLatin1String("vaapisink")); + m_sinkProperties = isVaapi ? new QVaapiSinkProperties(m_videoSink) : new QXVImageSinkProperties(m_videoSink); + + if (m_sinkProperties->hasShowPrerollFrame()) { + g_signal_connect(m_videoSink, "notify::show-preroll-frame", + G_CALLBACK(showPrerollFrameChanged), this); + } + } +} + +QGstreamerVideoOverlay::~QGstreamerVideoOverlay() +{ + if (m_videoSink) { + delete m_sinkProperties; + GstPad *pad = gst_element_get_static_pad(m_videoSink, "sink"); + removeProbeFromPad(pad); + gst_object_unref(GST_OBJECT(pad)); + gst_object_unref(GST_OBJECT(m_videoSink)); + } +} + GstElement *QGstreamerVideoOverlay::videoSink() const { return m_videoSink; @@ -209,11 +446,7 @@ void QGstreamerVideoOverlay::setWindowHandle_helper(WId id) #endif // Properties need to be reset when changing the winId. - setAspectRatioMode(m_aspectRatioMode); - setBrightness(m_brightness); - setContrast(m_contrast); - setHue(m_hue); - setSaturation(m_saturation); + m_sinkProperties->reset(); } } @@ -313,7 +546,7 @@ void QGstreamerVideoOverlay::updateIsActive() GstState state = GST_STATE(m_videoSink); gboolean showPreroll = true; - if (m_hasShowPrerollFrame) + if (m_sinkProperties->hasShowPrerollFrame()) g_object_get(G_OBJECT(m_videoSink), "show-preroll-frame", &showPreroll, NULL); bool newIsActive = (state == GST_STATE_PLAYING || (state == GST_STATE_PAUSED && showPreroll)); @@ -331,108 +564,56 @@ void QGstreamerVideoOverlay::showPrerollFrameChanged(GObject *, GParamSpec *, QG Qt::AspectRatioMode QGstreamerVideoOverlay::aspectRatioMode() const { - Qt::AspectRatioMode mode = Qt::KeepAspectRatio; - - if (m_hasForceAspectRatio) { - gboolean forceAR = false; - g_object_get(G_OBJECT(m_videoSink), "force-aspect-ratio", &forceAR, NULL); - if (!forceAR) - mode = Qt::IgnoreAspectRatio; - } - - return mode; + return m_sinkProperties->aspectRatioMode(); } void QGstreamerVideoOverlay::setAspectRatioMode(Qt::AspectRatioMode mode) { - if (m_hasForceAspectRatio) { - g_object_set(G_OBJECT(m_videoSink), - "force-aspect-ratio", - (mode == Qt::KeepAspectRatio), - (const char*)NULL); - } - - m_aspectRatioMode = mode; + m_sinkProperties->setAspectRatioMode(mode); } int QGstreamerVideoOverlay::brightness() const { - int brightness = 0; - - if (m_hasBrightness) - g_object_get(G_OBJECT(m_videoSink), "brightness", &brightness, NULL); - - return brightness / 10; + return m_sinkProperties->brightness(); } void QGstreamerVideoOverlay::setBrightness(int brightness) { - if (m_hasBrightness) { - g_object_set(G_OBJECT(m_videoSink), "brightness", brightness * 10, NULL); + if (m_sinkProperties->setBrightness(brightness)) emit brightnessChanged(brightness); - } - - m_brightness = brightness; } int QGstreamerVideoOverlay::contrast() const { - int contrast = 0; - - if (m_hasContrast) - g_object_get(G_OBJECT(m_videoSink), "contrast", &contrast, NULL); - - return contrast / 10; + return m_sinkProperties->contrast(); } void QGstreamerVideoOverlay::setContrast(int contrast) { - if (m_hasContrast) { - g_object_set(G_OBJECT(m_videoSink), "contrast", contrast * 10, NULL); + if (m_sinkProperties->setContrast(contrast)) emit contrastChanged(contrast); - } - - m_contrast = contrast; } int QGstreamerVideoOverlay::hue() const { - int hue = 0; - - if (m_hasHue) - g_object_get(G_OBJECT(m_videoSink), "hue", &hue, NULL); - - return hue / 10; + return m_sinkProperties->hue(); } void QGstreamerVideoOverlay::setHue(int hue) { - if (m_hasHue) { - g_object_set(G_OBJECT(m_videoSink), "hue", hue * 10, NULL); + if (m_sinkProperties->setHue(hue)) emit hueChanged(hue); - } - - m_hue = hue; } int QGstreamerVideoOverlay::saturation() const { - int saturation = 0; - - if (m_hasSaturation) - g_object_get(G_OBJECT(m_videoSink), "saturation", &saturation, NULL); - - return saturation / 10; + return m_sinkProperties->saturation(); } void QGstreamerVideoOverlay::setSaturation(int saturation) { - if (m_hasSaturation) { - g_object_set(G_OBJECT(m_videoSink), "saturation", saturation * 10, NULL); + if (m_sinkProperties->setSaturation(saturation)) emit saturationChanged(saturation); - } - - m_saturation = saturation; } QT_END_NAMESPACE diff --git a/src/multimedia/gsttools_headers/qgstreamervideooverlay_p.h b/src/multimedia/gsttools_headers/qgstreamervideooverlay_p.h index f3066fad8..4228f0fd0 100644 --- a/src/multimedia/gsttools_headers/qgstreamervideooverlay_p.h +++ b/src/multimedia/gsttools_headers/qgstreamervideooverlay_p.h @@ -58,6 +58,7 @@ QT_BEGIN_NAMESPACE +class QGstreamerSinkProperties; class QGstreamerVideoOverlay : public QObject , public QGstreamerSyncMessageFilter @@ -106,29 +107,17 @@ Q_SIGNALS: void saturationChanged(int saturation); private: - GstElement *findBestVideoSink() const; void setWindowHandle_helper(WId id); void updateIsActive(); void probeCaps(GstCaps *caps) override; static void showPrerollFrameChanged(GObject *, GParamSpec *, QGstreamerVideoOverlay *); - GstElement *m_videoSink; + GstElement *m_videoSink = nullptr; QSize m_nativeVideoSize; - bool m_isActive; - - bool m_hasForceAspectRatio; - bool m_hasBrightness; - bool m_hasContrast; - bool m_hasHue; - bool m_hasSaturation; - bool m_hasShowPrerollFrame; - - WId m_windowId; - Qt::AspectRatioMode m_aspectRatioMode; - int m_brightness; - int m_contrast; - int m_hue; - int m_saturation; + bool m_isActive = false; + + QGstreamerSinkProperties *m_sinkProperties = nullptr; + WId m_windowId = 0; }; QT_END_NAMESPACE -- cgit v1.2.3 From a429fb971beccf174f2df7f1ae8551a10d17d696 Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Wed, 29 Nov 2017 12:32:36 +0100 Subject: Gstreamer: Fix leak in prepare-window-handle message If the handler returns GST_BUS_DROP, it should unref the message, else the message should not be unreffed by the sync handler. The message is not going to be unreffed after handler call is made. Task-number: QTBUG-64142 Change-Id: Ib44f574e95457cdfab66b390c691a8b572987d66 Reviewed-by: Christian Stromme --- src/gsttools/qgstreamerbushelper.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/gsttools/qgstreamerbushelper.cpp b/src/gsttools/qgstreamerbushelper.cpp index bd35d4b0a..bad1d210a 100644 --- a/src/gsttools/qgstreamerbushelper.cpp +++ b/src/gsttools/qgstreamerbushelper.cpp @@ -143,8 +143,10 @@ static GstBusSyncReply syncGstBusFilter(GstBus* bus, GstMessage* message, QGstre QMutexLocker lock(&d->filterMutex); for (QGstreamerSyncMessageFilter *filter : qAsConst(d->syncFilters)) { - if (filter->processSyncMessage(QGstreamerMessage(message))) + if (filter->processSyncMessage(QGstreamerMessage(message))) { + gst_message_unref(message); return GST_BUS_DROP; + } } return GST_BUS_PASS; -- cgit v1.2.3 From efbb769b24e1a3b88326578042029876b09b4dea Mon Sep 17 00:00:00 2001 From: VaL Doroshchuk Date: Wed, 27 Sep 2017 17:37:25 +0200 Subject: Support changing of volume in 24-bit audio samples Introduced a fix to support changing of volume for 3 bytes samples audio stream. Task-number: QTBUG-60579 Change-Id: I4ba4a9a1cf65812ccbc46b40c78546875d5e4d73 Reviewed-by: Christian Stromme --- src/multimedia/audio/qaudiohelpers.cpp | 49 +++++++++++++++++++++ tests/auto/integration/qsoundeffect/test24.wav | Bin 0 -> 16482 bytes .../integration/qsoundeffect/tst_qsoundeffect.cpp | 27 ++++++++++++ 3 files changed, 76 insertions(+) create mode 100644 tests/auto/integration/qsoundeffect/test24.wav diff --git a/src/multimedia/audio/qaudiohelpers.cpp b/src/multimedia/audio/qaudiohelpers.cpp index 8aa4c090b..fae591477 100644 --- a/src/multimedia/audio/qaudiohelpers.cpp +++ b/src/multimedia/audio/qaudiohelpers.cpp @@ -43,6 +43,49 @@ QT_BEGIN_NAMESPACE +// Base implementation of 24 bits number. +// Used to adjust 3 bytes values by a factor. +// TODO: Uses little-endian only. +class Int24 +{ +public: + quint8 data[3]; + Int24(qint32 v) { + data[0] = v & 0xFF; + data[1] = (v & 0xFF00) >> 8; + data[2] = (v & 0xFF0000) >> 16; + } + template + T multiply(qreal factor, T v = 0) const { + v |= data[0]; + v |= data[1] << 8; + v |= data[2] << 16; + v *= factor; + return v; + } +}; + +class qint24: public Int24 +{ +public: + qint24(qint32 v): Int24(v) {} + qint24 operator*(qreal factor) const { + // Checks if it is a signed value. + qint32 v = (data[2] & 0x80) ? 0xFF000000 : 0; + return multiply(factor, v); + } +}; + +class quint24: public Int24 +{ +public: + quint24(quint32 v): Int24(v) {} + quint24 operator*(qreal factor) const { + return multiply(factor); + } +}; + + namespace QAudioHelperInternal { @@ -101,6 +144,12 @@ void qMultiplySamples(qreal factor, const QAudioFormat &format, const void* src, else if (format.sampleType() == QAudioFormat::UnSignedInt) QAudioHelperInternal::adjustUnsignedSamples(factor,src,dest,samplesCount); break; + case 24: + if (format.sampleType() == QAudioFormat::SignedInt) + QAudioHelperInternal::adjustSamples(factor,src,dest,samplesCount); + else if (format.sampleType() == QAudioFormat::UnSignedInt) + QAudioHelperInternal::adjustSamples(factor,src,dest,samplesCount); + break; default: if (format.sampleType() == QAudioFormat::SignedInt) QAudioHelperInternal::adjustSamples(factor,src,dest,samplesCount); diff --git a/tests/auto/integration/qsoundeffect/test24.wav b/tests/auto/integration/qsoundeffect/test24.wav new file mode 100644 index 000000000..9575aaaee Binary files /dev/null and b/tests/auto/integration/qsoundeffect/test24.wav differ diff --git a/tests/auto/integration/qsoundeffect/tst_qsoundeffect.cpp b/tests/auto/integration/qsoundeffect/tst_qsoundeffect.cpp index 5be889096..fa98c8b16 100644 --- a/tests/auto/integration/qsoundeffect/tst_qsoundeffect.cpp +++ b/tests/auto/integration/qsoundeffect/tst_qsoundeffect.cpp @@ -62,12 +62,14 @@ private slots: void testSetSourceWhilePlaying(); void testSupportedMimeTypes(); void testCorruptFile(); + void testPlaying24Bits(); private: QSoundEffect* sound; QUrl url; // test.wav: pcm_s16le, 48000 Hz, stereo, s16 QUrl url2; // test_tone.wav: pcm_s16le, 44100 Hz, mono QUrl urlCorrupted; // test_corrupted.wav: corrupted + QUrl url24Bits; // test24.wav pcm_s24le, 44100 Hz, mono }; void tst_QSoundEffect::init() @@ -105,6 +107,11 @@ void tst_QSoundEffect::initTestCase() QVERIFY2(!fullPath.isEmpty(), qPrintable(QStringLiteral("Unable to locate ") + testFileName)); urlCorrupted = QUrl::fromLocalFile(fullPath); + testFileName = QStringLiteral("test24.wav"); + fullPath = QFINDTESTDATA(testFileName); + QVERIFY2(!fullPath.isEmpty(), qPrintable(QStringLiteral("Unable to locate ") + testFileName)); + url24Bits = QUrl::fromLocalFile(fullPath); + sound = new QSoundEffect(this); QVERIFY(sound->source().isEmpty()); @@ -409,6 +416,26 @@ void tst_QSoundEffect::testCorruptFile() } } +void tst_QSoundEffect::testPlaying24Bits() +{ + sound->setLoopCount(QSoundEffect::Infinite); + sound->setSource(url24Bits); + QTestEventLoop::instance().enterLoop(1); + sound->play(); + QTestEventLoop::instance().enterLoop(1); + QTRY_COMPARE(sound->isPlaying(), true); + sound->stop(); + + QSignalSpy readSignal(sound, SIGNAL(volumeChanged())); + sound->setVolume(0.5); + QCOMPARE(sound->volume(), 0.5); + sound->play(); + QTestEventLoop::instance().enterLoop(1); + QTRY_COMPARE(sound->isPlaying(), true); + QCOMPARE(readSignal.count(), 1); + sound->stop(); +} + QTEST_MAIN(tst_QSoundEffect) #include "tst_qsoundeffect.moc" -- cgit v1.2.3 From 1d95eee694553feb30f415a1b3eee94caad53fb0 Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Mon, 8 Jan 2018 16:23:21 +0100 Subject: DirectShow: Add warning when not supported playback rate applied IMediaSeeking::SetRate() may return an error when not supported rate is being applied. Added a warning to inform user about incorrect rate value also fixed a bug when the rate has been always fell back to 1.0 instead of previous value. Task-number: QTBUG-55354 Change-Id: I85fb5572cba6920b461a023aef1bc09a981ab033 Reviewed-by: Christian Stromme --- src/plugins/directshow/player/directshowplayerservice.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plugins/directshow/player/directshowplayerservice.cpp b/src/plugins/directshow/player/directshowplayerservice.cpp index 8ee5d67a1..63f738bbe 100644 --- a/src/plugins/directshow/player/directshowplayerservice.cpp +++ b/src/plugins/directshow/player/directshowplayerservice.cpp @@ -1071,8 +1071,11 @@ void DirectShowPlayerService::doSetRate(QMutexLocker *locker) locker->relock(); if (!SUCCEEDED(hr)) { + qWarning("%s: Audio device or filter does not support rate: %.2f. " \ + "Falling back to previous value.", __FUNCTION__, m_rate); + double rate = 0.0; - m_rate = seeking->GetRate(&rate) + m_rate = SUCCEEDED(seeking->GetRate(&rate)) ? rate : 1.0; } -- cgit v1.2.3 From 4c7a376f4b4c43bc6626fe59815264f19573e288 Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Mon, 22 Jan 2018 16:03:41 +0100 Subject: DirectShow: Fix blank QVideoWidget when it is paused If playback is paused latest video frame is shown. If after that the window is deactivated (unfocused or hidden) the picture is cleared. And just empty area is shown. Provided following fixes: 1. Prevented clearing the painted video picture when the window is unfocused. 2. Repainted latest video frame again when the window gets back from hidden state to shown. Task-number: QTBUG-65780 Change-Id: I62b3c6e25133a7d08a5060a5ab9f6b35d927fbd4 Reviewed-by: Christian Stromme --- src/multimediawidgets/qvideowidget.cpp | 34 +++++----------------------------- src/multimediawidgets/qvideowidget.h | 4 ---- src/multimediawidgets/qvideowidget_p.h | 4 ---- 3 files changed, 5 insertions(+), 37 deletions(-) diff --git a/src/multimediawidgets/qvideowidget.cpp b/src/multimediawidgets/qvideowidget.cpp index a0161c17f..e9977c5a8 100644 --- a/src/multimediawidgets/qvideowidget.cpp +++ b/src/multimediawidgets/qvideowidget.cpp @@ -323,6 +323,9 @@ QWindowVideoWidgetBackend::QWindowVideoWidgetBackend( connect(control, SIGNAL(nativeSizeChanged()), m_widget, SLOT(_q_dimensionsChanged())); control->setWinId(widget->winId()); +#if defined(Q_OS_WIN) + m_widget->setUpdatesEnabled(false); +#endif } QWindowVideoWidgetBackend::~QWindowVideoWidgetBackend() @@ -392,16 +395,13 @@ void QWindowVideoWidgetBackend::showEvent() m_windowControl->setWinId(m_widget->winId()); updateDisplayRect(); -#if defined(Q_WS_WIN) - m_widget->setUpdatesEnabled(false); +#if defined(Q_OS_WIN) + m_windowControl->repaint(); #endif } void QWindowVideoWidgetBackend::hideEvent(QHideEvent *) { -#if defined(Q_WS_WIN) - m_widget->setUpdatesEnabled(true); -#endif } void QWindowVideoWidgetBackend::moveEvent(QMoveEvent *) @@ -427,16 +427,6 @@ void QWindowVideoWidgetBackend::paintEvent(QPaintEvent *event) event->accept(); } -#if defined(Q_WS_WIN) -bool QWindowVideoWidgetBackend::winEvent(MSG *message, long *) -{ - if (message->message == WM_PAINT) - m_windowControl->repaint(); - - return false; -} -#endif - void QVideoWidgetPrivate::setCurrentControl(QVideoWidgetControlInterface *control) { if (currentControl != control) { @@ -1011,20 +1001,6 @@ void QVideoWidget::paintEvent(QPaintEvent *event) } } - -#if defined(Q_WS_WIN) -/*! - \internal -*/ -bool QVideoWidget::winEvent(MSG *message, long *result) -{ - return d_func()->windowBackend && d_func()->windowBackend->winEvent(message, result) - ? true - : QWidget::winEvent(message, result); -} -#endif - - #include "moc_qvideowidget.cpp" #include "moc_qvideowidget_p.cpp" QT_END_NAMESPACE diff --git a/src/multimediawidgets/qvideowidget.h b/src/multimediawidgets/qvideowidget.h index 00b160821..b1e2da46b 100644 --- a/src/multimediawidgets/qvideowidget.h +++ b/src/multimediawidgets/qvideowidget.h @@ -107,10 +107,6 @@ protected: bool setMediaObject(QMediaObject *object) override; -#if defined(Q_WS_WIN) - bool winEvent(MSG *message, long *result); -#endif - QVideoWidget(QVideoWidgetPrivate &dd, QWidget *parent); QVideoWidgetPrivate *d_ptr; diff --git a/src/multimediawidgets/qvideowidget_p.h b/src/multimediawidgets/qvideowidget_p.h index 48b08e093..ef417b222 100644 --- a/src/multimediawidgets/qvideowidget_p.h +++ b/src/multimediawidgets/qvideowidget_p.h @@ -206,10 +206,6 @@ public: void moveEvent(QMoveEvent *event) override; void paintEvent(QPaintEvent *event) override; -#if defined(Q_WS_WIN) - bool winEvent(MSG *message, long *result); -#endif - private: void updateDisplayRect(); -- cgit v1.2.3 From 3b1f2ac5d3b78c33392a625a134c2a09390f3fba Mon Sep 17 00:00:00 2001 From: Val Doroshchuk Date: Mon, 15 Jan 2018 15:43:20 +0100 Subject: Fix target rectangle coordinates while painting image with QPainter QRectF::setX() may change the width. QRectF::setY() may change the height. If either width or height has been adjusted incorrect target rect is applied to draw an image which will cause some artefacts to be shown (like rectangle with a garbage) and incorrect size of actual content. Task-number: QTBUG-53594 Change-Id: Iee92aaf908952d7809e8ad62f8d1126b7ecac642 Reviewed-by: Christian Stromme --- src/multimediawidgets/qpaintervideosurface.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/multimediawidgets/qpaintervideosurface.cpp b/src/multimediawidgets/qpaintervideosurface.cpp index 0147690e1..0396f9fc0 100644 --- a/src/multimediawidgets/qpaintervideosurface.cpp +++ b/src/multimediawidgets/qpaintervideosurface.cpp @@ -202,12 +202,13 @@ QAbstractVideoSurface::Error QVideoSurfaceGenericPainter::paint( if (m_scanLineDirection == QVideoSurfaceFormat::BottomToTop) { transform.scale(1, -1); transform.translate(0, -target.bottom()); - targetRect.setY(0); + targetRect = QRectF(target.x(), 0, target.width(), target.height()); } + if (m_mirrored) { transform.scale(-1, 1); transform.translate(-target.right(), 0); - targetRect.setX(0); + targetRect = QRectF(0, targetRect.y(), target.width(), target.height()); } painter->setTransform(transform); painter->drawImage(targetRect, image, source); -- cgit v1.2.3 From 58d83703d7d5435a74d59bdb906ca6a76b54f78f Mon Sep 17 00:00:00 2001 From: Andre Hartmann Date: Sun, 11 Mar 2018 11:21:10 +0100 Subject: QSoundEffectPrivate: Use nullptr instead 0 or NULL Change-Id: I62e3d4d1284adeea457d754d63650b5c9b81e276 Reviewed-by: VaL Doroshchuk Reviewed-by: Christian Stromme --- src/multimedia/audio/qsoundeffect_pulse_p.cpp | 70 +++++++++++++------------- src/multimedia/audio/qsoundeffect_qaudio_p.cpp | 6 +-- 2 files changed, 39 insertions(+), 37 deletions(-) diff --git a/src/multimedia/audio/qsoundeffect_pulse_p.cpp b/src/multimedia/audio/qsoundeffect_pulse_p.cpp index 981d4c01f..77f8607a6 100644 --- a/src/multimedia/audio/qsoundeffect_pulse_p.cpp +++ b/src/multimedia/audio/qsoundeffect_pulse_p.cpp @@ -164,9 +164,9 @@ private Q_SLOTS: if (m_prepared) return; - m_context = 0; + m_context = nullptr; m_mainLoop = pa_threaded_mainloop_new(); - if (m_mainLoop == 0) { + if (m_mainLoop == nullptr) { qWarning("PulseAudioService: unable to create pulseaudio mainloop"); return; } @@ -182,11 +182,11 @@ private Q_SLOTS: lock(); m_context = pa_context_new(m_mainLoopApi, QString(QLatin1String("QtPulseAudio:%1")).arg(::getpid()).toLatin1().constData()); - if (m_context == 0) { + if (m_context == nullptr) { qWarning("PulseAudioService: Unable to create new pulseaudio context"); unlock(); pa_threaded_mainloop_free(m_mainLoop); - m_mainLoop = 0; + m_mainLoop = nullptr; onContextFailed(); return; } @@ -194,16 +194,16 @@ private Q_SLOTS: pa_context_set_state_callback(m_context, context_state_callback, this); const QByteArray srvStrEnv = qgetenv("QT_PULSE_SERVER_STRING"); - const char *srvStr = srvStrEnv.isNull() ? 0 : srvStrEnv.constData(); + const char *srvStr = srvStrEnv.isNull() ? nullptr : srvStrEnv.constData(); pa_context_flags_t flags = qEnvironmentVariableIsSet("QT_PULSE_NOAUTOSPAWN") ? PA_CONTEXT_NOAUTOSPAWN : (pa_context_flags_t)0; - if (pa_context_connect(m_context, srvStr, flags, 0) < 0) { + if (pa_context_connect(m_context, srvStr, flags, nullptr) < 0) { qWarning("PulseAudioService: pa_context_connect() failed"); pa_context_unref(m_context); unlock(); pa_threaded_mainloop_free(m_mainLoop); - m_mainLoop = 0; - m_context = 0; + m_mainLoop = nullptr; + m_context = nullptr; return; } unlock(); @@ -226,12 +226,12 @@ private: if (m_mainLoop) { pa_threaded_mainloop_stop(m_mainLoop); pa_threaded_mainloop_free(m_mainLoop); - m_mainLoop = 0; + m_mainLoop = nullptr; } if (m_context) { pa_context_unref(m_context); - m_context = 0; + m_context = nullptr; } m_prepared = false; @@ -338,7 +338,7 @@ public: qDebug() << "QSoundEffectRef(" << this << ") notifyDeleted"; #endif QMutexLocker locker(&m_mutex); - m_target = NULL; + m_target = nullptr; } private: @@ -349,7 +349,7 @@ private: QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent): QObject(parent), - m_pulseStream(0), + m_pulseStream(nullptr), m_sinkInputId(-1), m_emptying(false), m_sampleReady(false), @@ -362,7 +362,7 @@ QSoundEffectPrivate::QSoundEffectPrivate(QObject* parent): m_loopCount(1), m_runningCount(0), m_reloadCategory(false), - m_sample(0), + m_sample(nullptr), m_position(0), m_resourcesAvailable(false) { @@ -397,7 +397,7 @@ void QSoundEffectPrivate::release() unloadPulseStream(); if (m_sample) { m_sample->release(); - m_sample = 0; + m_sample = nullptr; } this->deleteLater(); @@ -435,7 +435,7 @@ void QSoundEffectPrivate::setCategory(const QString &category) QSoundEffectPrivate::~QSoundEffectPrivate() { QMediaResourcePolicy::destroyResourceSet(m_resources); - m_resources = 0; + m_resources = nullptr; m_ref->release(); pulseDaemon()->deref(); @@ -474,7 +474,7 @@ void QSoundEffectPrivate::setSource(const QUrl &url) disconnect(m_sample, SIGNAL(ready()), this, SLOT(sampleReady())); } m_sample->release(); - m_sample = 0; + m_sample = nullptr; } m_source = url; @@ -482,9 +482,9 @@ void QSoundEffectPrivate::setSource(const QUrl &url) setLoopsRemaining(0); if (m_pulseStream && !pa_stream_is_corked(m_pulseStream)) { - pa_stream_set_write_callback(m_pulseStream, 0, 0); - pa_stream_set_underflow_callback(m_pulseStream, 0, 0); - pa_operation *op = pa_stream_cork(m_pulseStream, 1, 0, 0); + pa_stream_set_write_callback(m_pulseStream, nullptr, nullptr); + pa_stream_set_underflow_callback(m_pulseStream, nullptr, nullptr); + pa_operation *op = pa_stream_cork(m_pulseStream, 1, nullptr, nullptr); if (op) pa_operation_unref(op); else @@ -676,8 +676,8 @@ void QSoundEffectPrivate::emptyStream(EmptyStreamOptions options) PulseDaemonLocker locker; m_emptying = true; - pa_stream_set_write_callback(m_pulseStream, 0, 0); - pa_stream_set_underflow_callback(m_pulseStream, 0, 0); + pa_stream_set_write_callback(m_pulseStream, nullptr, nullptr); + pa_stream_set_underflow_callback(m_pulseStream, nullptr, nullptr); pa_operation *op = pa_stream_flush(m_pulseStream, flushCompleteCb, m_ref->getRef()); if (op) pa_operation_unref(op); @@ -696,7 +696,8 @@ void QSoundEffectPrivate::emptyComplete(void *stream, bool reload) m_emptying = false; if ((pa_stream *)stream == m_pulseStream) { - pa_operation *op = pa_stream_cork(m_pulseStream, 1, reload ? stream_cork_callback : 0, m_ref->getRef()); + pa_operation *op = pa_stream_cork(m_pulseStream, 1, + reload ? stream_cork_callback : nullptr, m_ref->getRef()); if (op) pa_operation_unref(op); else @@ -780,13 +781,13 @@ void QSoundEffectPrivate::unloadPulseStream() m_sinkInputId = -1; PulseDaemonLocker locker; if (m_pulseStream) { - pa_stream_set_state_callback(m_pulseStream, 0, 0); - pa_stream_set_write_callback(m_pulseStream, 0, 0); - pa_stream_set_underflow_callback(m_pulseStream, 0, 0); + pa_stream_set_state_callback(m_pulseStream, nullptr, nullptr); + pa_stream_set_write_callback(m_pulseStream, nullptr, nullptr); + pa_stream_set_underflow_callback(m_pulseStream, nullptr, nullptr); pa_stream_disconnect(m_pulseStream); pa_stream_unref(m_pulseStream); disconnect(pulseDaemon(), SIGNAL(contextFailed()), this, SLOT(contextFailed())); - m_pulseStream = 0; + m_pulseStream = nullptr; m_reloadCategory = false; // category will be reloaded when we connect anyway } } @@ -896,7 +897,7 @@ int QSoundEffectPrivate::writeToStream(const void *data, int size) if (volume < 1.0f) { // Don't use PulseAudio volume, as it might affect all other streams of the same category // or even affect the system volume if flat volumes are enabled - void *dest = NULL; + void *dest = nullptr; size_t nbytes = size; if (pa_stream_begin_write(m_pulseStream, &dest, &nbytes) < 0) { qWarning("QSoundEffect(pulseaudio): pa_stream_begin_write, error = %s", @@ -907,7 +908,7 @@ int QSoundEffectPrivate::writeToStream(const void *data, int size) size = int(nbytes); QAudioHelperInternal::qMultiplySamples(volume, m_sample->format(), data, dest, size); data = dest; - writeDoneCb = NULL; + writeDoneCb = nullptr; } if (pa_stream_write(m_pulseStream, data, size, writeDoneCb, 0, PA_SEEK_RELATIVE) < 0) { @@ -928,7 +929,7 @@ void QSoundEffectPrivate::playSample() #endif Q_ASSERT(m_pulseStream); Q_ASSERT(pa_stream_get_state(m_pulseStream) == PA_STREAM_READY); - pa_operation *o = pa_stream_cork(m_pulseStream, 0, 0, 0); + pa_operation *o = pa_stream_cork(m_pulseStream, 0, nullptr, nullptr); if (o) pa_operation_unref(o); } @@ -999,14 +1000,15 @@ void QSoundEffectPrivate::createPulseStream() pa_proplist *propList = pa_proplist_new(); if (!m_category.isNull()) pa_proplist_sets(propList, PA_PROP_MEDIA_ROLE, m_category.toLatin1().constData()); - pa_stream *stream = pa_stream_new_with_proplist(pulseDaemon()->context(), m_name.constData(), &m_pulseSpec, 0, propList); + pa_stream *stream = pa_stream_new_with_proplist(pulseDaemon()->context(), m_name.constData(), + &m_pulseSpec, nullptr, propList); pa_proplist_free(propList); connect(pulseDaemon(), SIGNAL(contextFailed()), this, SLOT(contextFailed())); - if (stream == 0) { + if (stream == nullptr) { qWarning("QSoundEffect(pulseaudio): Failed to create stream"); - m_pulseStream = 0; + m_pulseStream = nullptr; setStatus(QSoundEffect::Error); setPlaying(false); return; @@ -1018,8 +1020,8 @@ void QSoundEffectPrivate::createPulseStream() } m_pulseStream = stream; - if (pa_stream_connect_playback(m_pulseStream, 0, 0, - PA_STREAM_START_CORKED, 0, 0) < 0) { + if (pa_stream_connect_playback(m_pulseStream, nullptr, nullptr, + PA_STREAM_START_CORKED, nullptr, nullptr) < 0) { qWarning("QSoundEffect(pulseaudio): Failed to connect stream, error = %s", pa_strerror(pa_context_errno(pulseDaemon()->context()))); } diff --git a/src/multimedia/audio/qsoundeffect_qaudio_p.cpp b/src/multimedia/audio/qsoundeffect_qaudio_p.cpp index 7dcbf934a..bf96f16ae 100644 --- a/src/multimedia/audio/qsoundeffect_qaudio_p.cpp +++ b/src/multimedia/audio/qsoundeffect_qaudio_p.cpp @@ -129,7 +129,7 @@ void QSoundEffectPrivate::setSource(const QUrl &url) disconnect(d->m_sample, SIGNAL(ready()), d, SLOT(sampleReady())); } d->m_sample->release(); - d->m_sample = 0; + d->m_sample = nullptr; } setStatus(QSoundEffect::Loading); @@ -308,8 +308,8 @@ PrivateSoundSource::PrivateSoundSource(QSoundEffectPrivate* s): m_runningCount(0), m_playing(false), m_status(QSoundEffect::Null), - m_audioOutput(0), - m_sample(0), + m_audioOutput(nullptr), + m_sample(nullptr), m_muted(false), m_volume(1.0), m_sampleReady(false), -- cgit v1.2.3