diff options
author | Yoann Lopes <yoann.lopes@theqtcompany.com> | 2015-11-23 17:44:01 +0100 |
---|---|---|
committer | Yoann Lopes <yoann.lopes@theqtcompany.com> | 2015-11-23 17:44:51 +0100 |
commit | 0757ff1c4add6bd4f6499c04969760765662efa3 (patch) | |
tree | 1c86054c53ee65fbfa69b670830a61fe9db1f6ab | |
parent | 11df4e75e4eca82d28dc147fcefb29d62b38a5dc (diff) | |
parent | 9937c67decc5b81eaa25fff8d773cc7c2e6ff838 (diff) | |
download | qtmultimedia-0757ff1c4add6bd4f6499c04969760765662efa3.tar.gz |
Merge remote-tracking branch 'origin/5.6' into dev
Change-Id: I0bee3f4e8721b9d2067495dde17be87a4b906245
71 files changed, 1083 insertions, 340 deletions
diff --git a/config.tests/wmp/wmp.pro b/config.tests/wmp/wmp.pro deleted file mode 100644 index 563de1453..000000000 --- a/config.tests/wmp/wmp.pro +++ /dev/null @@ -1,7 +0,0 @@ -CONFIG -= qt -CONFIG += console - -SOURCES += main.cpp - -LIBS += -lstrmiids -lole32 -lOleaut32 -!wince*:LIBS += -luser32 -lgdi32 diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectBillboard.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectBillboard.qml index 021b8d778..c4e1b204e 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectBillboard.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectBillboard.qml @@ -39,10 +39,16 @@ Effect { name: "Grid Spacing" value: 0.5 } + onDataChanged: updateGrid() + } + + function updateGrid() + { + grid = parameters.get(0).value * 10; } // Transform slider values, and bind result to shader uniforms - property real grid: parameters.get(0).value * 10 + property real grid: 5.0 property real step_x: 0.0015625 property real step_y: targetHeight ? (step_x * targetWidth / targetHeight) : 0.0 diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectBlackAndWhite.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectBlackAndWhite.qml index 8cfe5a78a..f1e53e005 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectBlackAndWhite.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectBlackAndWhite.qml @@ -39,10 +39,15 @@ Effect { name: "Threshold" value: 0.5 } + onDataChanged: updateThreshold() } + function updateThreshold() + { + threshold = parameters.get(0).value; + } // Transform slider values, and bind result to shader uniforms - property real threshold: parameters.get(0).value + property real threshold: 0.5 fragmentShaderFilename: "blackandwhite.fsh" } diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectGaussianBlur.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectGaussianBlur.qml index 3ccf1c678..7941eac63 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectGaussianBlur.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectGaussianBlur.qml @@ -44,17 +44,37 @@ Item { name: "Radius" value: 0.5 } + onDataChanged: updateBlurSize() + } + + function updateBlurSize() + { + if ((targetHeight > 0) && (targetWidth > 0)) + { + verticalBlurSize = 4.0 * parameters.get(0).value / targetHeight; + horizontalBlurSize = 4.0 * parameters.get(0).value / targetWidth; + } } property alias targetWidth: verticalShader.targetWidth property alias targetHeight: verticalShader.targetHeight property alias source: verticalShader.source + property alias horizontalBlurSize: horizontalShader.blurSize + property alias verticalBlurSize: verticalShader.blurSize + Effect { id: verticalShader anchors.fill: parent dividerValue: parent.dividerValue - property real blurSize: 4.0 * parent.parameters.get(0).value / targetHeight + property real blurSize: 0.0 + + onTargetHeightChanged: { + updateBlurSize() + } + onTargetWidthChanged: { + updateBlurSize() + } fragmentShaderFilename: "gaussianblur_v.fsh" } @@ -62,7 +82,7 @@ Item { id: horizontalShader anchors.fill: parent dividerValue: parent.dividerValue - property real blurSize: 4.0 * parent.parameters.get(0).value / parent.targetWidth + property real blurSize: 0.0 fragmentShaderFilename: "gaussianblur_h.fsh" source: horizontalShaderSource diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectIsolate.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectIsolate.qml index 24a281db6..5af8b6fd6 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectIsolate.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectIsolate.qml @@ -43,11 +43,18 @@ Effect { name: "Width" value: 0.5 } + onDataChanged: updateParameters() + } + + function updateParameters() + { + targetHue = parameters.get(0).value * 360 + windowWidth = parameters.get(1).value * 60 } // Transform slider values, and bind result to shader uniforms - property real targetHue: parameters.get(0).value * 360 - property real windowWidth: parameters.get(1).value * 60 + property real targetHue: 0.5 * 360 + property real windowWidth: 0.5 * 60 fragmentShaderFilename: "isolate.fsh" } diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectMagnify.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectMagnify.qml index 5e8c9e0ef..76535ea7e 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectMagnify.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectMagnify.qml @@ -46,6 +46,13 @@ Effect { name: "Diffraction" value: 0.5 } + onDataChanged: updateParameters() + } + + function updateParameters() + { + radius = parameters.get(0).value * 100; + diffractionIndex = parameters.get(1).value; } property real posX: -1 @@ -59,8 +66,8 @@ Effect { } // Transform slider values, and bind result to shader uniforms - property real radius: parameters.get(0).value * 100 - property real diffractionIndex: parameters.get(1).value + property real radius: 0.5 * 100 + property real diffractionIndex: 0.5 onTargetWidthChanged: { if (posX == -1) diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPageCurl.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPageCurl.qml index 4ccad8b58..4980b1ddf 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPageCurl.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPageCurl.qml @@ -40,10 +40,16 @@ Effect { name: "Extent" value: 0.5 } + onDataChanged: updateParameters() + } + + function updateParameters() + { + curlExtent = 1.0 - parameters.get(0).value; } // Transform slider values, and bind result to shader uniforms - property real curlExtent: 1.0 - parameters.get(0).value + property real curlExtent: 0.5 fragmentShaderFilename: "pagecurl.fsh" } diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPixelate.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPixelate.qml index cea15c285..40453f93f 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPixelate.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPixelate.qml @@ -39,10 +39,16 @@ Effect { name: "Granularity" value: 0.5 } + onDataChanged: updateParameters() + } + + function updateParameters() + { + granularity = parameters.get(0).value * 20.0; } // Transform slider values, and bind result to shader uniforms - property real granularity: parameters.get(0).value * 20 + property real granularity: 0.5 * 20 fragmentShaderFilename: "pixelate.fsh" } diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPosterize.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPosterize.qml index bba48dcd8..c8b1893d1 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPosterize.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectPosterize.qml @@ -39,10 +39,16 @@ Effect { name: "Gamma" value: 0.5 } + onDataChanged: updateParameters() + } + + function updateParameters() + { + gamma = parameters.get(0).value; } // Transform slider values, and bind result to shader uniforms - property real gamma: parameters.get(0).value + property real gamma: 0.5 property real numColors: 8.0 diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectRipple.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectRipple.qml index e47eadfb4..67eae30ea 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectRipple.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectRipple.qml @@ -44,11 +44,18 @@ Effect { name: "Frequency" value: 0.5 } + onDataChanged: updateParameters() + } + + function updateParameters() + { + amplitude = parameters.get(0).value * 0.03; + n = parameters.get(1).value * 7; } // Transform slider values, and bind result to shader uniforms - property real amplitude: parameters.get(0).value * 0.03 - property real n: parameters.get(1).value * 7 + property real amplitude: 0.5 * 0.03 + property real n: 0.5 * 7 property real pixDens: Screen.pixelDensity property real time: 0 diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSharpen.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSharpen.qml index 9b80dd4b2..094270c01 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSharpen.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSharpen.qml @@ -39,10 +39,16 @@ Effect { name: "Sharpness" value: 0.5 } + onDataChanged: updateParameters() + } + + function updateParameters() + { + amount = parameters.get(0).value * 18; } // Transform slider values, and bind result to shader uniforms - property real amount: parameters.get(0).value * 18 + property real amount: 0.5 * 18 fragmentShaderFilename: "sharpen.fsh" } diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectShockwave.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectShockwave.qml index 0e0520c29..a20f2445e 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectShockwave.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectShockwave.qml @@ -40,11 +40,18 @@ Effect { name: "Amplitude" value: 0.5 } + onDataChanged: updateParameters() + } + + function updateParameters() + { + granularity = parameters.get(0).value * 20; + weight = parameters.get(0).value; } // Transform slider values, and bind result to shader uniforms - property real granularity: parameters.get(0).value * 20 - property real weight: parameters.get(0).value + property real granularity: 0.5 * 20 + property real weight: 0.5 property real centerX property real centerY diff --git a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSobelEdgeDetection1.qml b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSobelEdgeDetection1.qml index 8da5c26be..936571c89 100644 --- a/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSobelEdgeDetection1.qml +++ b/examples/multimedia/video/qmlvideofx/qml/qmlvideofx/EffectSobelEdgeDetection1.qml @@ -39,10 +39,16 @@ Effect { name: "Threshold" value: 0.5 } + onDataChanged: updateMixLevel() + } + + function updateMixLevel() + { + mixLevel = parameters.get(0).value; } // Transform slider values, and bind result to shader uniforms - property real mixLevel: parameters.get(0).value + property real mixLevel: 0.5 property real targetSize: 250 - (200 * mixLevel) // TODO: fix ... property real resS: targetSize property real resT: targetSize diff --git a/qtmultimedia.pro b/qtmultimedia.pro index 1225ffb61..98bb3152f 100644 --- a/qtmultimedia.pro +++ b/qtmultimedia.pro @@ -6,10 +6,9 @@ win32 { qtCompileTest(directshow) { qtCompileTest(wshellitem) } + qtCompileTest(evr) qtCompileTest(wmsdk) - qtCompileTest(wmp) contains(QT_CONFIG, wmf-backend): qtCompileTest(wmf) - qtCompileTest(evr) } else:mac { qtCompileTest(avfoundation) } else:qnx { diff --git a/src/gsttools/qgstutils.cpp b/src/gsttools/qgstutils.cpp index 50a56232a..b9e04e3f1 100644 --- a/src/gsttools/qgstutils.cpp +++ b/src/gsttools/qgstutils.cpp @@ -44,6 +44,7 @@ #include <qaudioformat.h> #include <QtCore/qelapsedtimer.h> #include <QtMultimedia/qvideosurfaceformat.h> +#include <private/qmultimediautils_p.h> #include <gst/audio/audio.h> #include <gst/video/video.h> @@ -1531,6 +1532,15 @@ GList *qt_gst_video_sinks() return list; } +void qt_gst_util_double_to_fraction(gdouble src, gint *dest_n, gint *dest_d) +{ +#if GST_CHECK_VERSION(0, 10, 26) + gst_util_double_to_fraction(src, dest_n, dest_d); +#else + qt_real_to_fraction(src, dest_n, dest_d); +#endif +} + QDebug operator <<(QDebug debug, GstCaps *caps) { if (caps) { diff --git a/src/multimedia/gsttools_headers/qgstutils_p.h b/src/multimedia/gsttools_headers/qgstutils_p.h index cf677c321..124805727 100644 --- a/src/multimedia/gsttools_headers/qgstutils_p.h +++ b/src/multimedia/gsttools_headers/qgstutils_p.h @@ -152,6 +152,7 @@ GstCaps *qt_gst_caps_normalize(GstCaps *caps); const gchar *qt_gst_element_get_factory_name(GstElement *element); gboolean qt_gst_caps_can_intersect(const GstCaps * caps1, const GstCaps * caps2); GList *qt_gst_video_sinks(); +void qt_gst_util_double_to_fraction(gdouble src, gint *dest_n, gint *dest_d); QDebug operator <<(QDebug debug, GstCaps *caps); diff --git a/src/multimedia/multimedia.pro b/src/multimedia/multimedia.pro index e3f368cf4..b16a792fb 100644 --- a/src/multimedia/multimedia.pro +++ b/src/multimedia/multimedia.pro @@ -26,7 +26,8 @@ PRIVATE_HEADERS += \ qmediaresourcepolicy_p.h \ qmediaresourceset_p.h \ qmediastoragelocation_p.h \ - qmediaopenglhelper_p.h + qmediaopenglhelper_p.h \ + qmultimediautils_p.h PUBLIC_HEADERS += \ qmediabindableinterface.h \ @@ -53,7 +54,8 @@ SOURCES += \ qmediaresourcepolicy_p.cpp \ qmediaresourceset_p.cpp \ qmediastoragelocation.cpp \ - qmultimedia.cpp + qmultimedia.cpp \ + qmultimediautils.cpp CONFIG += simd optimize_full diff --git a/src/multimedia/qmultimediautils.cpp b/src/multimedia/qmultimediautils.cpp new file mode 100644 index 000000000..6635e755d --- /dev/null +++ b/src/multimedia/qmultimediautils.cpp @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qmultimediautils_p.h" + +QT_BEGIN_NAMESPACE + +void qt_real_to_fraction(qreal value, int *numerator, int *denominator) +{ + if (!numerator || !denominator) + return; + + const int dMax = 1000; + int n1 = 0, d1 = 1, n2 = 1, d2 = 1; + qreal mid = 0.; + while (d1 <= dMax && d2 <= dMax) { + mid = qreal(n1 + n2) / (d1 + d2); + + if (qAbs(value - mid) < 0.000001) { + if (d1 + d2 <= dMax) { + *numerator = n1 + n2; + *denominator = d1 + d2; + return; + } else if (d2 > d1) { + *numerator = n2; + *denominator = d2; + return; + } else { + *numerator = n1; + *denominator = d1; + return; + } + } else if (value > mid) { + n1 = n1 + n2; + d1 = d1 + d2; + } else { + n2 = n1 + n2; + d2 = d1 + d2; + } + } + + if (d1 > dMax) { + *numerator = n2; + *denominator = d2; + } else { + *numerator = n1; + *denominator = d1; + } +} + +QT_END_NAMESPACE diff --git a/src/multimedia/qmultimediautils_p.h b/src/multimedia/qmultimediautils_p.h new file mode 100644 index 000000000..61bbb6008 --- /dev/null +++ b/src/multimedia/qmultimediautils_p.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QMULTIMEDIAUTILS_P_H +#define QMULTIMEDIAUTILS_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtMultimedia/qmultimedia.h> + +QT_BEGIN_NAMESPACE + +Q_MULTIMEDIA_EXPORT void qt_real_to_fraction(qreal value, int *numerator, int *denominator); + +QT_END_NAMESPACE + +#endif // QMULTIMEDIAUTILS_P_H + diff --git a/src/plugins/audiocapture/audiocapturesession.cpp b/src/plugins/audiocapture/audiocapturesession.cpp index 2b300964a..1b183db26 100644 --- a/src/plugins/audiocapture/audiocapturesession.cpp +++ b/src/plugins/audiocapture/audiocapturesession.cpp @@ -88,6 +88,8 @@ AudioCaptureSession::AudioCaptureSession(QObject *parent) , m_audioInput(0) , m_deviceInfo(QAudioDeviceInfo::defaultInputDevice()) , m_wavFile(true) + , m_volume(1.0) + , m_muted(false) { m_format = m_deviceInfo.preferredFormat(); } @@ -312,6 +314,8 @@ void AudioCaptureSession::record() file.write((char*)&header,sizeof(CombinedHeader)); } + setVolumeHelper(m_muted ? 0 : m_volume); + file.startProbes(m_format); m_audioInput->start(qobject_cast<QIODevice*>(&file)); } else { @@ -400,4 +404,51 @@ void AudioCaptureSession::setCaptureDevice(const QString &deviceName) m_deviceInfo = QAudioDeviceInfo::defaultInputDevice(); } +qreal AudioCaptureSession::volume() const +{ + return m_volume; +} + +bool AudioCaptureSession::isMuted() const +{ + return m_muted; +} + +void AudioCaptureSession::setVolume(qreal v) +{ + qreal boundedVolume = qBound(qreal(0), v, qreal(1)); + + if (m_volume == boundedVolume) + return; + + m_volume = boundedVolume; + + if (!m_muted) + setVolumeHelper(m_volume); + + emit volumeChanged(m_volume); +} + +void AudioCaptureSession::setMuted(bool muted) +{ + if (m_muted == muted) + return; + + m_muted = muted; + + setVolumeHelper(m_muted ? 0 : m_volume); + + emit mutedChanged(m_muted); +} + +void AudioCaptureSession::setVolumeHelper(qreal volume) +{ + if (!m_audioInput) + return; + + m_audioInput->setVolume(volume); +} + + + QT_END_NAMESPACE diff --git a/src/plugins/audiocapture/audiocapturesession.h b/src/plugins/audiocapture/audiocapturesession.h index 188312905..da30053ad 100644 --- a/src/plugins/audiocapture/audiocapturesession.h +++ b/src/plugins/audiocapture/audiocapturesession.h @@ -96,11 +96,19 @@ public: void setCaptureDevice(const QString &deviceName); + void setVolume(qreal v); + qreal volume() const; + + void setMuted(bool muted); + bool isMuted() const; + signals: void stateChanged(QMediaRecorder::State state); void statusChanged(QMediaRecorder::Status status); void positionChanged(qint64 position); void actualLocationChanged(const QUrl &location); + void volumeChanged(qreal volume); + void mutedChanged(bool muted); void error(int error, const QString &errorString); private slots: @@ -114,6 +122,8 @@ private: void setStatus(QMediaRecorder::Status status); + void setVolumeHelper(qreal volume); + QDir defaultDir() const; QString generateFileName(const QString &requestedName, const QString &extension) const; @@ -129,6 +139,8 @@ private: QAudioDeviceInfo m_deviceInfo; QAudioFormat m_format; bool m_wavFile; + qreal m_volume; + bool m_muted; // WAV header stuff diff --git a/src/plugins/audiocapture/audiomediarecordercontrol.cpp b/src/plugins/audiocapture/audiomediarecordercontrol.cpp index 432ee3d08..d011d864e 100644 --- a/src/plugins/audiocapture/audiomediarecordercontrol.cpp +++ b/src/plugins/audiocapture/audiomediarecordercontrol.cpp @@ -50,6 +50,10 @@ AudioMediaRecorderControl::AudioMediaRecorderControl(QObject *parent) this, SIGNAL(statusChanged(QMediaRecorder::Status))); connect(m_session, SIGNAL(actualLocationChanged(QUrl)), this, SIGNAL(actualLocationChanged(QUrl))); + connect(m_session, &AudioCaptureSession::volumeChanged, + this, &AudioMediaRecorderControl::volumeChanged); + connect(m_session, &AudioCaptureSession::mutedChanged, + this, &AudioMediaRecorderControl::mutedChanged); connect(m_session, SIGNAL(error(int,QString)), this, SIGNAL(error(int,QString))); } @@ -85,13 +89,12 @@ qint64 AudioMediaRecorderControl::duration() const bool AudioMediaRecorderControl::isMuted() const { - return false; + return m_session->isMuted(); } qreal AudioMediaRecorderControl::volume() const { - //TODO: implement muting and audio gain - return 1.0; + return m_session->volume(); } void AudioMediaRecorderControl::setState(QMediaRecorder::State state) @@ -101,14 +104,12 @@ void AudioMediaRecorderControl::setState(QMediaRecorder::State state) void AudioMediaRecorderControl::setMuted(bool muted) { - if (muted) - qWarning("Muting the audio recording is not supported."); + m_session->setMuted(muted); } void AudioMediaRecorderControl::setVolume(qreal volume) { - if (!qFuzzyCompare(volume, qreal(1.0))) - qWarning("Changing the audio recording volume is not supported."); + m_session->setVolume(volume); } QT_END_NAMESPACE diff --git a/src/plugins/avfoundation/camera/avfcameraservice.mm b/src/plugins/avfoundation/camera/avfcameraservice.mm index fd473b37b..20156f06f 100644 --- a/src/plugins/avfoundation/camera/avfcameraservice.mm +++ b/src/plugins/avfoundation/camera/avfcameraservice.mm @@ -203,18 +203,15 @@ QMediaControl *AVFCameraService::requestControl(const char *name) void AVFCameraService::releaseControl(QMediaControl *control) { - if (m_videoOutput == control) { - m_session->setVideoOutput(0); - delete m_videoOutput; - m_videoOutput = 0; - } AVFMediaVideoProbeControl *videoProbe = qobject_cast<AVFMediaVideoProbeControl *>(control); if (videoProbe) { m_session->removeProbe(videoProbe); delete videoProbe; - return; + } else if (m_videoOutput == control) { + m_session->setVideoOutput(0); + delete m_videoOutput; + m_videoOutput = 0; } - } AVFMediaRecorderControl *AVFCameraService::recorderControl() const diff --git a/src/plugins/avfoundation/camera/avfcamerautility.h b/src/plugins/avfoundation/camera/avfcamerautility.h index 42005a502..64093645f 100644 --- a/src/plugins/avfoundation/camera/avfcamerautility.h +++ b/src/plugins/avfoundation/camera/avfcamerautility.h @@ -160,8 +160,6 @@ inline QSysInfo::MacVersion qt_OS_limit(QSysInfo::MacVersion osxVersion, typedef QPair<qreal, qreal> AVFPSRange; AVFPSRange qt_connection_framerates(AVCaptureConnection *videoConnection); -typedef QPair<int, int> AVFRational; -AVFRational qt_float_to_rational(qreal par, int limit); #if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_7, __IPHONE_7_0) diff --git a/src/plugins/avfoundation/camera/avfcamerautility.mm b/src/plugins/avfoundation/camera/avfcamerautility.mm index f45169d07..3668bb124 100644 --- a/src/plugins/avfoundation/camera/avfcamerautility.mm +++ b/src/plugins/avfoundation/camera/avfcamerautility.mm @@ -36,6 +36,7 @@ #include <QtCore/qvector.h> #include <QtCore/qpair.h> +#include <private/qmultimediautils_p.h> #include <functional> #include <algorithm> @@ -77,42 +78,6 @@ AVFPSRange qt_connection_framerates(AVCaptureConnection *videoConnection) return newRange; } -AVFRational qt_float_to_rational(qreal par, int limit) -{ - Q_ASSERT(limit > 0); - - // In Qt we represent pixel aspect ratio - // as a rational number (we use QSize). - // AVFoundation describes dimensions in pixels - // and in pixels with width multiplied by PAR. - // Represent this PAR as a ratio. - int a = 0, b = 1, c = 1, d = 1; - qreal mid = 0.; - while (b <= limit && d <= limit) { - mid = qreal(a + c) / (b + d); - - if (qAbs(par - mid) < 0.000001) { - if (b + d <= limit) - return AVFRational(a + c, b + d); - else if (d > b) - return AVFRational(c, d); - else - return AVFRational(a, b); - } else if (par > mid) { - a = a + c; - b = b + d; - } else { - c = a + c; - d = b + d; - } - } - - if (b > limit) - return AVFRational(c, d); - - return AVFRational(a, b); -} - #if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_7, __IPHONE_7_0) namespace { @@ -264,10 +229,13 @@ QSize qt_device_format_pixel_aspect_ratio(AVCaptureDeviceFormat *format) if (!res.width || !resPAR.width) return QSize(); - const AVFRational asRatio(qt_float_to_rational(resPAR.width > res.width - ? res.width / qreal(resPAR.width) - : resPAR.width / qreal(res.width), 200)); - return QSize(asRatio.first, asRatio.second); + int n, d; + qt_real_to_fraction(resPAR.width > res.width + ? res.width / qreal(resPAR.width) + : resPAR.width / qreal(res.width), + &n, &d); + + return QSize(n, d); } AVCaptureDeviceFormat *qt_find_best_resolution_match(AVCaptureDevice *captureDevice, diff --git a/src/plugins/avfoundation/camera/avfcameraviewfindersettingscontrol.mm b/src/plugins/avfoundation/camera/avfcameraviewfindersettingscontrol.mm index 05f28898d..c5da1c343 100644 --- a/src/plugins/avfoundation/camera/avfcameraviewfindersettingscontrol.mm +++ b/src/plugins/avfoundation/camera/avfcameraviewfindersettingscontrol.mm @@ -45,6 +45,7 @@ #include <QtCore/qvector.h> #include <QtCore/qdebug.h> #include <QtCore/qlist.h> +#include <private/qmultimediautils_p.h> #include <algorithm> @@ -129,8 +130,9 @@ CMTime qt_adjusted_frame_duration(AVFrameRateRange *range, qreal fps) if (fps >= range.maxFrameRate) return range.minFrameDuration; - const AVFRational timeAsRational(qt_float_to_rational(1. / fps, 1000)); - return CMTimeMake(timeAsRational.first, timeAsRational.second); + int n, d; + qt_real_to_fraction(1. / fps, &n, &d); + return CMTimeMake(n, d); } void qt_set_framerate_limits(AVCaptureDevice *captureDevice, diff --git a/src/plugins/common/evr.pri b/src/plugins/common/evr.pri new file mode 100644 index 000000000..f951f6730 --- /dev/null +++ b/src/plugins/common/evr.pri @@ -0,0 +1,8 @@ +INCLUDEPATH += $$PWD/evr + +qtHaveModule(widgets): QT += widgets + +HEADERS += $$PWD/evr/evrvideowindowcontrol.h \ + $$PWD/evr/evrdefs.h + +SOURCES += $$PWD/evr/evrvideowindowcontrol.cpp diff --git a/src/plugins/common/evr/evrdefs.h b/src/plugins/common/evr/evrdefs.h new file mode 100644 index 000000000..ce6ca6584 --- /dev/null +++ b/src/plugins/common/evr/evrdefs.h @@ -0,0 +1,127 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef EVRDEFS_H +#define EVRDEFS_H + +#include <d3d9.h> +#include <Evr9.h> +#include <dxva2api.h> + +// The following is required to compile with MinGW + +#ifdef __GNUC__ +typedef struct MFVideoNormalizedRect { + float left; + float top; + float right; + float bottom; +} MFVideoNormalizedRect; +#endif + +#ifndef __IMFGetService_INTERFACE_DEFINED__ +#define __IMFGetService_INTERFACE_DEFINED__ +DEFINE_GUID(IID_IMFGetService, 0xfa993888, 0x4383, 0x415a, 0xa9,0x30, 0xdd,0x47,0x2a,0x8c,0xf6,0xf7); +MIDL_INTERFACE("fa993888-4383-415a-a930-dd472a8cf6f7") +IMFGetService : public IUnknown +{ + virtual HRESULT STDMETHODCALLTYPE GetService(REFGUID, REFIID, LPVOID *) = 0; +}; +#ifdef __CRT_UUID_DECL +__CRT_UUID_DECL(IMFGetService, 0xfa993888, 0x4383, 0x415a, 0xa9,0x30, 0xdd,0x47,0x2a,0x8c,0xf6,0xf7) +#endif +#endif // __IMFGetService_INTERFACE_DEFINED__ + +#ifndef __IMFVideoDisplayControl_INTERFACE_DEFINED__ +#define __IMFVideoDisplayControl_INTERFACE_DEFINED__ +typedef enum MFVideoAspectRatioMode +{ + MFVideoARMode_None = 0, + MFVideoARMode_PreservePicture = 0x1, + MFVideoARMode_PreservePixel = 0x2, + MFVideoARMode_NonLinearStretch = 0x4, + MFVideoARMode_Mask = 0x7 +} MFVideoAspectRatioMode; + +DEFINE_GUID(IID_IMFVideoDisplayControl, 0xa490b1e4, 0xab84, 0x4d31, 0xa1,0xb2, 0x18,0x1e,0x03,0xb1,0x07,0x7a); +MIDL_INTERFACE("a490b1e4-ab84-4d31-a1b2-181e03b1077a") +IMFVideoDisplayControl : public IUnknown +{ + virtual HRESULT STDMETHODCALLTYPE GetNativeVideoSize(SIZE *, SIZE *) = 0; + virtual HRESULT STDMETHODCALLTYPE GetIdealVideoSize(SIZE *, SIZE *) = 0; + virtual HRESULT STDMETHODCALLTYPE SetVideoPosition(const MFVideoNormalizedRect *, const LPRECT) = 0; + virtual HRESULT STDMETHODCALLTYPE GetVideoPosition(MFVideoNormalizedRect *, LPRECT) = 0; + virtual HRESULT STDMETHODCALLTYPE SetAspectRatioMode(DWORD) = 0; + virtual HRESULT STDMETHODCALLTYPE GetAspectRatioMode(DWORD *) = 0; + virtual HRESULT STDMETHODCALLTYPE SetVideoWindow(HWND) = 0; + virtual HRESULT STDMETHODCALLTYPE GetVideoWindow(HWND *) = 0; + virtual HRESULT STDMETHODCALLTYPE RepaintVideo(void) = 0; + virtual HRESULT STDMETHODCALLTYPE GetCurrentImage(BITMAPINFOHEADER *, BYTE **, DWORD *, LONGLONG *) = 0; + virtual HRESULT STDMETHODCALLTYPE SetBorderColor(COLORREF) = 0; + virtual HRESULT STDMETHODCALLTYPE GetBorderColor(COLORREF *) = 0; + virtual HRESULT STDMETHODCALLTYPE SetRenderingPrefs(DWORD) = 0; + virtual HRESULT STDMETHODCALLTYPE GetRenderingPrefs(DWORD *) = 0; + virtual HRESULT STDMETHODCALLTYPE SetFullscreen(BOOL) = 0; + virtual HRESULT STDMETHODCALLTYPE GetFullscreen(BOOL *) = 0; +}; +#ifdef __CRT_UUID_DECL +__CRT_UUID_DECL(IMFVideoDisplayControl, 0xa490b1e4, 0xab84, 0x4d31, 0xa1,0xb2, 0x18,0x1e,0x03,0xb1,0x07,0x7a) +#endif +#endif // __IMFVideoDisplayControl_INTERFACE_DEFINED__ + +#ifndef __IMFVideoProcessor_INTERFACE_DEFINED__ +#define __IMFVideoProcessor_INTERFACE_DEFINED__ +DEFINE_GUID(IID_IMFVideoProcessor, 0x6AB0000C, 0xFECE, 0x4d1f, 0xA2,0xAC, 0xA9,0x57,0x35,0x30,0x65,0x6E); +MIDL_INTERFACE("6AB0000C-FECE-4d1f-A2AC-A9573530656E") +IMFVideoProcessor : public IUnknown +{ + virtual HRESULT STDMETHODCALLTYPE GetAvailableVideoProcessorModes(UINT *, GUID **) = 0; + virtual HRESULT STDMETHODCALLTYPE GetVideoProcessorCaps(LPGUID, DXVA2_VideoProcessorCaps *) = 0; + virtual HRESULT STDMETHODCALLTYPE GetVideoProcessorMode(LPGUID) = 0; + virtual HRESULT STDMETHODCALLTYPE SetVideoProcessorMode(LPGUID) = 0; + virtual HRESULT STDMETHODCALLTYPE GetProcAmpRange(DWORD, DXVA2_ValueRange *) = 0; + virtual HRESULT STDMETHODCALLTYPE GetProcAmpValues(DWORD, DXVA2_ProcAmpValues *) = 0; + virtual HRESULT STDMETHODCALLTYPE SetProcAmpValues(DWORD, DXVA2_ProcAmpValues *) = 0; + virtual HRESULT STDMETHODCALLTYPE GetFilteringRange(DWORD, DXVA2_ValueRange *) = 0; + virtual HRESULT STDMETHODCALLTYPE GetFilteringValue(DWORD, DXVA2_Fixed32 *) = 0; + virtual HRESULT STDMETHODCALLTYPE SetFilteringValue(DWORD, DXVA2_Fixed32 *) = 0; + virtual HRESULT STDMETHODCALLTYPE GetBackgroundColor(COLORREF *) = 0; + virtual HRESULT STDMETHODCALLTYPE SetBackgroundColor(COLORREF) = 0; +}; +#ifdef __CRT_UUID_DECL +__CRT_UUID_DECL(IMFVideoProcessor, 0x6AB0000C, 0xFECE, 0x4d1f, 0xA2,0xAC, 0xA9,0x57,0x35,0x30,0x65,0x6E) +#endif +#endif // __IMFVideoProcessor_INTERFACE_DEFINED__ + +#endif // EVRDEFS_H + diff --git a/src/plugins/wmf/player/evr9videowindowcontrol.cpp b/src/plugins/common/evr/evrvideowindowcontrol.cpp index e94918dba..faa23d6e5 100644 --- a/src/plugins/wmf/player/evr9videowindowcontrol.cpp +++ b/src/plugins/common/evr/evrvideowindowcontrol.cpp @@ -3,7 +3,7 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Mobility Components. +** This file is part of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL21$ ** Commercial License Usage @@ -31,14 +31,16 @@ ** ****************************************************************************/ -#include "evr9videowindowcontrol.h" -#include <QtWidgets/qwidget.h> -#include <QtCore/qdebug.h> -#include <QtCore/qglobal.h> +#include "evrvideowindowcontrol.h" -Evr9VideoWindowControl::Evr9VideoWindowControl(QObject *parent) +#ifndef QT_NO_WIDGETS +#include <qwidget.h> +#endif + +EvrVideoWindowControl::EvrVideoWindowControl(QObject *parent) : QVideoWindowControl(parent) , m_windowId(0) + , m_windowColor(RGB(0, 0, 0)) , m_dirtyValues(0) , m_aspectRatioMode(Qt::KeepAspectRatio) , m_brightness(0) @@ -46,68 +48,83 @@ Evr9VideoWindowControl::Evr9VideoWindowControl(QObject *parent) , m_hue(0) , m_saturation(0) , m_fullScreen(false) - , m_currentActivate(0) - , m_evrSink(0) , m_displayControl(0) , m_processor(0) { } -Evr9VideoWindowControl::~Evr9VideoWindowControl() +EvrVideoWindowControl::~EvrVideoWindowControl() { clear(); } -void Evr9VideoWindowControl::clear() +bool EvrVideoWindowControl::setEvr(IUnknown *evr) { - if (m_processor) - m_processor->Release(); - if (m_displayControl) - m_displayControl->Release(); - if (m_evrSink) - m_evrSink->Release(); - if (m_currentActivate) { - m_currentActivate->ShutdownObject(); - m_currentActivate->Release(); + clear(); + + if (!evr) + return true; + + static const GUID mr_VIDEO_RENDER_SERVICE = { 0x1092a86c, 0xab1a, 0x459a, {0xa3, 0x36, 0x83, 0x1f, 0xbc, 0x4d, 0x11, 0xff} }; + static const GUID mr_VIDEO_MIXER_SERVICE = { 0x73cd2fc, 0x6cf4, 0x40b7, {0x88, 0x59, 0xe8, 0x95, 0x52, 0xc8, 0x41, 0xf8} }; + IMFGetService *service = NULL; + + if (SUCCEEDED(evr->QueryInterface(IID_PPV_ARGS(&service))) + && SUCCEEDED(service->GetService(mr_VIDEO_RENDER_SERVICE, IID_PPV_ARGS(&m_displayControl)))) { + + service->GetService(mr_VIDEO_MIXER_SERVICE, IID_PPV_ARGS(&m_processor)); + + setWinId(m_windowId); + setDisplayRect(m_displayRect); + setAspectRatioMode(m_aspectRatioMode); + m_dirtyValues = DXVA2_ProcAmp_Brightness | DXVA2_ProcAmp_Contrast | DXVA2_ProcAmp_Hue | DXVA2_ProcAmp_Saturation; + applyImageControls(); } - m_processor = NULL; - m_displayControl = NULL; - m_evrSink = NULL; - m_currentActivate = NULL; + if (service) + service->Release(); + + return m_displayControl != NULL; } -void Evr9VideoWindowControl::releaseActivate() +void EvrVideoWindowControl::clear() { - clear(); + if (m_displayControl) + m_displayControl->Release(); + m_displayControl = NULL; + + if (m_processor) + m_processor->Release(); + m_processor = NULL; } -WId Evr9VideoWindowControl::winId() const +WId EvrVideoWindowControl::winId() const { return m_windowId; } -void Evr9VideoWindowControl::setWinId(WId id) +void EvrVideoWindowControl::setWinId(WId id) { m_windowId = id; +#ifndef QT_NO_WIDGETS if (QWidget *widget = QWidget::find(m_windowId)) { const QColor color = widget->palette().color(QPalette::Window); m_windowColor = RGB(color.red(), color.green(), color.blue()); } +#endif - if (m_displayControl) { + if (m_displayControl) m_displayControl->SetVideoWindow(HWND(m_windowId)); - } } -QRect Evr9VideoWindowControl::displayRect() const +QRect EvrVideoWindowControl::displayRect() const { return m_displayRect; } -void Evr9VideoWindowControl::setDisplayRect(const QRect &rect) +void EvrVideoWindowControl::setDisplayRect(const QRect &rect) { m_displayRect = rect; @@ -140,19 +157,19 @@ void Evr9VideoWindowControl::setDisplayRect(const QRect &rect) } } -bool Evr9VideoWindowControl::isFullScreen() const +bool EvrVideoWindowControl::isFullScreen() const { return m_fullScreen; } -void Evr9VideoWindowControl::setFullScreen(bool fullScreen) +void EvrVideoWindowControl::setFullScreen(bool fullScreen) { if (m_fullScreen == fullScreen) return; emit fullScreenChanged(m_fullScreen = fullScreen); } -void Evr9VideoWindowControl::repaint() +void EvrVideoWindowControl::repaint() { QSize size = nativeSize(); if (size.width() > 0 && size.height() > 0 @@ -181,7 +198,7 @@ void Evr9VideoWindowControl::repaint() } } -QSize Evr9VideoWindowControl::nativeSize() const +QSize EvrVideoWindowControl::nativeSize() const { QSize size; if (m_displayControl) { @@ -192,12 +209,12 @@ QSize Evr9VideoWindowControl::nativeSize() const return size; } -Qt::AspectRatioMode Evr9VideoWindowControl::aspectRatioMode() const +Qt::AspectRatioMode EvrVideoWindowControl::aspectRatioMode() const { return m_aspectRatioMode; } -void Evr9VideoWindowControl::setAspectRatioMode(Qt::AspectRatioMode mode) +void EvrVideoWindowControl::setAspectRatioMode(Qt::AspectRatioMode mode) { m_aspectRatioMode = mode; @@ -222,12 +239,12 @@ void Evr9VideoWindowControl::setAspectRatioMode(Qt::AspectRatioMode mode) } } -int Evr9VideoWindowControl::brightness() const +int EvrVideoWindowControl::brightness() const { return m_brightness; } -void Evr9VideoWindowControl::setBrightness(int brightness) +void EvrVideoWindowControl::setBrightness(int brightness) { if (m_brightness == brightness) return; @@ -236,17 +253,17 @@ void Evr9VideoWindowControl::setBrightness(int brightness) m_dirtyValues |= DXVA2_ProcAmp_Brightness; - setProcAmpValues(); + applyImageControls(); emit brightnessChanged(brightness); } -int Evr9VideoWindowControl::contrast() const +int EvrVideoWindowControl::contrast() const { return m_contrast; } -void Evr9VideoWindowControl::setContrast(int contrast) +void EvrVideoWindowControl::setContrast(int contrast) { if (m_contrast == contrast) return; @@ -255,17 +272,17 @@ void Evr9VideoWindowControl::setContrast(int contrast) m_dirtyValues |= DXVA2_ProcAmp_Contrast; - setProcAmpValues(); + applyImageControls(); emit contrastChanged(contrast); } -int Evr9VideoWindowControl::hue() const +int EvrVideoWindowControl::hue() const { return m_hue; } -void Evr9VideoWindowControl::setHue(int hue) +void EvrVideoWindowControl::setHue(int hue) { if (m_hue == hue) return; @@ -274,17 +291,17 @@ void Evr9VideoWindowControl::setHue(int hue) m_dirtyValues |= DXVA2_ProcAmp_Hue; - setProcAmpValues(); + applyImageControls(); emit hueChanged(hue); } -int Evr9VideoWindowControl::saturation() const +int EvrVideoWindowControl::saturation() const { return m_saturation; } -void Evr9VideoWindowControl::setSaturation(int saturation) +void EvrVideoWindowControl::setSaturation(int saturation) { if (m_saturation == saturation) return; @@ -293,41 +310,12 @@ void Evr9VideoWindowControl::setSaturation(int saturation) m_dirtyValues |= DXVA2_ProcAmp_Saturation; - setProcAmpValues(); + applyImageControls(); emit saturationChanged(saturation); } -IMFActivate* Evr9VideoWindowControl::createActivate() -{ - clear(); - - if (FAILED(MFCreateVideoRendererActivate(0, &m_currentActivate))) { - qWarning() << "Failed to create evr video renderer activate!"; - return 0; - } - if (FAILED(m_currentActivate->ActivateObject(IID_IMFMediaSink, (LPVOID*)(&m_evrSink)))) { - qWarning() << "Failed to activate evr media sink!"; - return 0; - } - if (FAILED(MFGetService(m_evrSink, MR_VIDEO_RENDER_SERVICE, IID_PPV_ARGS(&m_displayControl)))) { - qWarning() << "Failed to get display control from evr media sink!"; - return 0; - } - if (FAILED(MFGetService(m_evrSink, MR_VIDEO_MIXER_SERVICE, IID_PPV_ARGS(&m_processor)))) { - qWarning() << "Failed to get video processor from evr media sink!"; - return 0; - } - - setWinId(m_windowId); - setDisplayRect(m_displayRect); - setAspectRatioMode(m_aspectRatioMode); - m_dirtyValues = DXVA2_ProcAmp_Brightness | DXVA2_ProcAmp_Contrast | DXVA2_ProcAmp_Hue | DXVA2_ProcAmp_Saturation; - - return m_currentActivate; -} - -void Evr9VideoWindowControl::setProcAmpValues() +void EvrVideoWindowControl::applyImageControls() { if (m_processor) { DXVA2_ProcAmpValues values; @@ -350,7 +338,7 @@ void Evr9VideoWindowControl::setProcAmpValues() } } -DXVA2_Fixed32 Evr9VideoWindowControl::scaleProcAmpValue(DWORD prop, int value) const +DXVA2_Fixed32 EvrVideoWindowControl::scaleProcAmpValue(DWORD prop, int value) const { float scaledValue = 0.0; diff --git a/src/plugins/wmf/player/evr9videowindowcontrol.h b/src/plugins/common/evr/evrvideowindowcontrol.h index 05486f987..beb82ec05 100644 --- a/src/plugins/wmf/player/evr9videowindowcontrol.h +++ b/src/plugins/common/evr/evrvideowindowcontrol.h @@ -31,23 +31,23 @@ ** ****************************************************************************/ -#ifndef EVR9VIDEOWINDOWCONTROL_H -#define EVR9VIDEOWINDOWCONTROL_H +#ifndef EVRVIDEOWINDOWCONTROL_H +#define EVRVIDEOWINDOWCONTROL_H #include "qvideowindowcontrol.h" -#include <Mfidl.h> -#include <d3d9.h> -#include <Evr9.h> +#include "evrdefs.h" QT_USE_NAMESPACE -class Evr9VideoWindowControl : public QVideoWindowControl +class EvrVideoWindowControl : public QVideoWindowControl { Q_OBJECT public: - Evr9VideoWindowControl(QObject *parent = 0); - ~Evr9VideoWindowControl(); + EvrVideoWindowControl(QObject *parent = 0); + ~EvrVideoWindowControl(); + + bool setEvr(IUnknown *evr); WId winId() const; void setWinId(WId id); @@ -77,10 +77,7 @@ public: int saturation() const; void setSaturation(int saturation); - IMFActivate* createActivate(); - void releaseActivate(); - - void setProcAmpValues(); + void applyImageControls(); private: void clear(); @@ -97,8 +94,6 @@ private: int m_saturation; bool m_fullScreen; - IMFActivate *m_currentActivate; - IMFMediaSink *m_evrSink; IMFVideoDisplayControl *m_displayControl; IMFVideoProcessor *m_processor; }; diff --git a/src/plugins/directshow/directshow.pro b/src/plugins/directshow/directshow.pro index 7815927db..4d7183923 100644 --- a/src/plugins/directshow/directshow.pro +++ b/src/plugins/directshow/directshow.pro @@ -13,11 +13,6 @@ SOURCES += dsserviceplugin.cpp !config_wmsdk: DEFINES += QT_NO_WMSDK -qtHaveModule(widgets) { - QT += multimediawidgets - DEFINES += HAVE_WIDGETS -} - mingw: DEFINES += NO_DSHOW_STRSAFE !config_wmf: include(player/player.pri) diff --git a/src/plugins/directshow/player/directshowaudioendpointcontrol.cpp b/src/plugins/directshow/player/directshowaudioendpointcontrol.cpp index 798a94102..d063447e3 100644 --- a/src/plugins/directshow/player/directshowaudioendpointcontrol.cpp +++ b/src/plugins/directshow/player/directshowaudioendpointcontrol.cpp @@ -44,7 +44,7 @@ DirectShowAudioEndpointControl::DirectShowAudioEndpointControl( , m_deviceEnumerator(0) { if (CreateBindCtx(0, &m_bindContext) == S_OK) { - m_deviceEnumerator = com_new<ICreateDevEnum>(CLSID_SystemDeviceEnum, IID_ICreateDevEnum); + m_deviceEnumerator = com_new<ICreateDevEnum>(CLSID_SystemDeviceEnum); updateEndpoints(); diff --git a/src/plugins/directshow/player/directshowevrvideowindowcontrol.cpp b/src/plugins/directshow/player/directshowevrvideowindowcontrol.cpp new file mode 100644 index 000000000..7bffe47d2 --- /dev/null +++ b/src/plugins/directshow/player/directshowevrvideowindowcontrol.cpp @@ -0,0 +1,63 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "directshowevrvideowindowcontrol.h" + +#include "directshowglobal.h" + +DirectShowEvrVideoWindowControl::DirectShowEvrVideoWindowControl(QObject *parent) + : EvrVideoWindowControl(parent) + , m_evrFilter(NULL) +{ +} + +DirectShowEvrVideoWindowControl::~DirectShowEvrVideoWindowControl() +{ + if (m_evrFilter) + m_evrFilter->Release(); +} + +IBaseFilter *DirectShowEvrVideoWindowControl::filter() +{ + static const GUID clsid_EnhancendVideoRenderer = { 0xfa10746c, 0x9b63, 0x4b6c, {0xbc, 0x49, 0xfc, 0x30, 0xe, 0xa5, 0xf2, 0x56} }; + + if (!m_evrFilter) { + m_evrFilter = com_new<IBaseFilter>(clsid_EnhancendVideoRenderer); + if (!setEvr(m_evrFilter)) { + m_evrFilter->Release(); + m_evrFilter = NULL; + } + } + + return m_evrFilter; +} diff --git a/config.tests/wmp/main.cpp b/src/plugins/directshow/player/directshowevrvideowindowcontrol.h index 95883c62e..46171812b 100644 --- a/config.tests/wmp/main.cpp +++ b/src/plugins/directshow/player/directshowevrvideowindowcontrol.h @@ -3,7 +3,7 @@ ** Copyright (C) 2015 The Qt Company Ltd. ** Contact: http://www.qt.io/licensing/ ** -** This file is part of the Qt Mobility Components. +** This file is part of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL21$ ** Commercial License Usage @@ -30,13 +30,26 @@ ** $QT_END_LICENSE$ ** ****************************************************************************/ -#ifndef _WIN32_WCE -#include <wmp.h> -#else -#include <wmpcore.h> -#endif -int main(int, char**) +#ifndef DIRECTSHOWEVRVIDEOWINDOWCONTROL_H +#define DIRECTSHOWEVRVIDEOWINDOWCONTROL_H + +#include "evrvideowindowcontrol.h" + +struct IBaseFilter; + +QT_USE_NAMESPACE + +class DirectShowEvrVideoWindowControl : public EvrVideoWindowControl { - return 0; -} +public: + DirectShowEvrVideoWindowControl(QObject *parent = 0); + ~DirectShowEvrVideoWindowControl(); + + IBaseFilter *filter(); + +private: + IBaseFilter *m_evrFilter; +}; + +#endif // DIRECTSHOWEVRVIDEOWINDOWCONTROL_H diff --git a/src/plugins/directshow/player/directshowglobal.h b/src/plugins/directshow/player/directshowglobal.h index 68cb23649..d8f1d1200 100644 --- a/src/plugins/directshow/player/directshowglobal.h +++ b/src/plugins/directshow/player/directshowglobal.h @@ -46,6 +46,18 @@ template <typename T> T *com_cast(IUnknown *unknown, const IID &iid) : 0; } +template <typename T> T *com_new(const IID &clsid) +{ + T *object = 0; + return CoCreateInstance( + clsid, + NULL, + CLSCTX_INPROC_SERVER, + IID_PPV_ARGS(&object)) == S_OK + ? object + : 0; +} + template <typename T> T *com_new(const IID &clsid, const IID &iid) { T *object = 0; diff --git a/src/plugins/directshow/player/directshowioreader.cpp b/src/plugins/directshow/player/directshowioreader.cpp index bee072d3b..298d099d2 100644 --- a/src/plugins/directshow/player/directshowioreader.cpp +++ b/src/plugins/directshow/player/directshowioreader.cpp @@ -132,7 +132,7 @@ HRESULT DirectShowIOReader::RequestAllocator( return S_OK; } else { - *ppActual = com_new<IMemAllocator>(CLSID_MemoryAllocator, IID_IMemAllocator); + *ppActual = com_new<IMemAllocator>(CLSID_MemoryAllocator); if (*ppActual) { if ((*ppActual)->SetProperties(pProps, &actualProperties) != S_OK) { diff --git a/src/plugins/directshow/player/directshowiosource.cpp b/src/plugins/directshow/player/directshowiosource.cpp index 424120fd8..e1034a9c6 100644 --- a/src/plugins/directshow/player/directshowiosource.cpp +++ b/src/plugins/directshow/player/directshowiosource.cpp @@ -413,7 +413,7 @@ HRESULT DirectShowIOSource::tryConnect(IPin *pin, const AM_MEDIA_TYPE *type) hr = VFW_E_NO_TRANSPORT; if (IMemInputPin *memPin = com_cast<IMemInputPin>(pin, IID_IMemInputPin)) { - if ((m_allocator = com_new<IMemAllocator>(CLSID_MemoryAllocator, IID_IMemAllocator))) { + if ((m_allocator = com_new<IMemAllocator>(CLSID_MemoryAllocator))) { ALLOCATOR_PROPERTIES properties; if (memPin->GetAllocatorRequirements(&properties) == S_OK || m_allocator->GetProperties(&properties) == S_OK) { diff --git a/src/plugins/directshow/player/directshowplayerservice.cpp b/src/plugins/directshow/player/directshowplayerservice.cpp index b73fa5c4c..07427583d 100644 --- a/src/plugins/directshow/player/directshowplayerservice.cpp +++ b/src/plugins/directshow/player/directshowplayerservice.cpp @@ -38,8 +38,10 @@ #include "directshowmetadatacontrol.h" #include "directshowplayercontrol.h" #include "directshowvideorenderercontrol.h" -#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR) #include "vmr9videowindowcontrol.h" + +#ifdef HAVE_EVR +#include "directshowevrvideowindowcontrol.h" #endif #ifndef QT_NO_WMSDK @@ -79,9 +81,7 @@ DirectShowPlayerService::DirectShowPlayerService(QObject *parent) , m_playerControl(0) , m_metaDataControl(0) , m_videoRendererControl(0) -#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR) , m_videoWindowControl(0) -#endif , m_audioEndpointControl(0) , m_taskThread(0) , m_loop(qt_directShowEventLoop()) @@ -140,9 +140,7 @@ DirectShowPlayerService::~DirectShowPlayerService() delete m_audioEndpointControl; delete m_metaDataControl; delete m_videoRendererControl; -#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR) delete m_videoWindowControl; -#endif ::CloseHandle(m_taskHandle); } @@ -156,11 +154,7 @@ QMediaControl *DirectShowPlayerService::requestControl(const char *name) } else if (qstrcmp(name, QMetaDataReaderControl_iid) == 0) { return m_metaDataControl; } else if (qstrcmp(name, QVideoRendererControl_iid) == 0) { -#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR) if (!m_videoRendererControl && !m_videoWindowControl) { -#else - if (!m_videoRendererControl) { -#endif m_videoRendererControl = new DirectShowVideoRendererControl(m_loop); connect(m_videoRendererControl, SIGNAL(filterChanged()), @@ -168,16 +162,28 @@ QMediaControl *DirectShowPlayerService::requestControl(const char *name) return m_videoRendererControl; } -#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR) } else if (qstrcmp(name, QVideoWindowControl_iid) == 0) { if (!m_videoRendererControl && !m_videoWindowControl) { - m_videoWindowControl = new Vmr9VideoWindowControl; + IBaseFilter *filter; - setVideoOutput(m_videoWindowControl->filter()); +#ifdef HAVE_EVR + DirectShowEvrVideoWindowControl *evrControl = new DirectShowEvrVideoWindowControl; + if ((filter = evrControl->filter())) + m_videoWindowControl = evrControl; + else + delete evrControl; +#endif + // Fall back to the VMR9 if the EVR is not available + if (!m_videoWindowControl) { + Vmr9VideoWindowControl *vmr9Control = new Vmr9VideoWindowControl; + filter = vmr9Control->filter(); + m_videoWindowControl = vmr9Control; + } + + setVideoOutput(filter); return m_videoWindowControl; } -#endif } return 0; } @@ -193,14 +199,12 @@ void DirectShowPlayerService::releaseControl(QMediaControl *control) delete m_videoRendererControl; m_videoRendererControl = 0; -#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR) } else if (control == m_videoWindowControl) { setVideoOutput(0); delete m_videoWindowControl; m_videoWindowControl = 0; -#endif } } @@ -275,8 +279,7 @@ void DirectShowPlayerService::doSetUrlSource(QMutexLocker *locker) static const GUID iid_IFileSourceFilter = { 0x56a868a6, 0x0ad4, 0x11ce, {0xb0, 0x3a, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70} }; - if (IFileSourceFilter *fileSource = com_new<IFileSourceFilter>( - clsid_WMAsfReader, iid_IFileSourceFilter)) { + if (IFileSourceFilter *fileSource = com_new<IFileSourceFilter>(clsid_WMAsfReader, iid_IFileSourceFilter)) { locker->unlock(); hr = fileSource->Load(reinterpret_cast<const OLECHAR *>(m_url.toString().utf16()), 0); @@ -324,6 +327,7 @@ void DirectShowPlayerService::doSetUrlSource(QMutexLocker *locker) m_error = QMediaPlayer::FormatError; m_errorString = QString(); break; + case E_FAIL: case E_OUTOFMEMORY: case VFW_E_CANNOT_LOAD_SOURCE_FILTER: case VFW_E_NOT_FOUND: diff --git a/src/plugins/directshow/player/directshowplayerservice.h b/src/plugins/directshow/player/directshowplayerservice.h index f4da103dc..edfde105e 100644 --- a/src/plugins/directshow/player/directshowplayerservice.h +++ b/src/plugins/directshow/player/directshowplayerservice.h @@ -51,12 +51,10 @@ class DirectShowAudioEndpointControl; class DirectShowMetaDataControl; class DirectShowPlayerControl; class DirectShowVideoRendererControl; -#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR) -class Vmr9VideoWindowControl; -#endif QT_BEGIN_NAMESPACE class QMediaContent; +class QVideoWindowControl; QT_END_NAMESPACE QT_USE_NAMESPACE @@ -172,9 +170,7 @@ private: DirectShowPlayerControl *m_playerControl; DirectShowMetaDataControl *m_metaDataControl; DirectShowVideoRendererControl *m_videoRendererControl; -#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR) - Vmr9VideoWindowControl *m_videoWindowControl; -#endif + QVideoWindowControl *m_videoWindowControl; DirectShowAudioEndpointControl *m_audioEndpointControl; QThread *m_taskThread; diff --git a/src/plugins/directshow/player/directshowvideorenderercontrol.cpp b/src/plugins/directshow/player/directshowvideorenderercontrol.cpp index da4764880..6a1580ea5 100644 --- a/src/plugins/directshow/player/directshowvideorenderercontrol.cpp +++ b/src/plugins/directshow/player/directshowvideorenderercontrol.cpp @@ -45,7 +45,8 @@ DirectShowVideoRendererControl::DirectShowVideoRendererControl(DirectShowEventLo DirectShowVideoRendererControl::~DirectShowVideoRendererControl() { - delete m_filter; + if (m_filter) + m_filter->Release(); } QAbstractVideoSurface *DirectShowVideoRendererControl::surface() const @@ -68,7 +69,8 @@ void DirectShowVideoRendererControl::setSurface(QAbstractVideoSurface *surface) emit filterChanged(); - delete existingFilter; + if (existingFilter) + existingFilter->Release(); } } diff --git a/src/plugins/directshow/player/player.pri b/src/plugins/directshow/player/player.pri index c5c934a38..8586ea5da 100644 --- a/src/plugins/directshow/player/player.pri +++ b/src/plugins/directshow/player/player.pri @@ -1,5 +1,9 @@ INCLUDEPATH += $$PWD +LIBS += -lstrmiids -ldmoguids -luuid -lmsdmo -lole32 -loleaut32 -lgdi32 + +qtHaveModule(widgets): QT += widgets + DEFINES += QMEDIA_DIRECTSHOW_PLAYER HEADERS += \ @@ -17,7 +21,8 @@ HEADERS += \ $$PWD/directshowsamplescheduler.h \ $$PWD/directshowvideorenderercontrol.h \ $$PWD/mediasamplevideobuffer.h \ - $$PWD/videosurfacefilter.h + $$PWD/videosurfacefilter.h \ + $$PWD/vmr9videowindowcontrol.h SOURCES += \ $$PWD/directshowaudioendpointcontrol.cpp \ @@ -33,14 +38,16 @@ SOURCES += \ $$PWD/directshowsamplescheduler.cpp \ $$PWD/directshowvideorenderercontrol.cpp \ $$PWD/mediasamplevideobuffer.cpp \ - $$PWD/videosurfacefilter.cpp + $$PWD/videosurfacefilter.cpp \ + $$PWD/vmr9videowindowcontrol.cpp -qtHaveModule(widgets):!simulator { - HEADERS += \ - $$PWD/vmr9videowindowcontrol.h +config_evr { + DEFINES += HAVE_EVR - SOURCES += \ - $$PWD/vmr9videowindowcontrol.cpp + include($$PWD/../../common/evr.pri) + + HEADERS += $$PWD/directshowevrvideowindowcontrol.h + SOURCES += $$PWD/directshowevrvideowindowcontrol.cpp } config_wshellitem { @@ -48,6 +55,3 @@ config_wshellitem { } else { DEFINES += QT_NO_SHELLITEM } - -LIBS += -lstrmiids -ldmoguids -luuid -lmsdmo -lole32 -loleaut32 -lgdi32 - diff --git a/src/plugins/directshow/player/videosurfacefilter.cpp b/src/plugins/directshow/player/videosurfacefilter.cpp index 901d2e908..1fa7329cc 100644 --- a/src/plugins/directshow/player/videosurfacefilter.cpp +++ b/src/plugins/directshow/player/videosurfacefilter.cpp @@ -69,7 +69,7 @@ VideoSurfaceFilter::VideoSurfaceFilter( VideoSurfaceFilter::~VideoSurfaceFilter() { - Q_ASSERT(m_ref == 1); + Q_ASSERT(m_ref == 0); } HRESULT VideoSurfaceFilter::QueryInterface(REFIID riid, void **ppvObject) @@ -110,8 +110,8 @@ ULONG VideoSurfaceFilter::AddRef() ULONG VideoSurfaceFilter::Release() { ULONG ref = InterlockedDecrement(&m_ref); - - Q_ASSERT(ref != 0); + if (ref == 0) + delete this; return ref; } diff --git a/src/plugins/directshow/player/vmr9videowindowcontrol.cpp b/src/plugins/directshow/player/vmr9videowindowcontrol.cpp index 48ff6c2c3..853ca031c 100644 --- a/src/plugins/directshow/player/vmr9videowindowcontrol.cpp +++ b/src/plugins/directshow/player/vmr9videowindowcontrol.cpp @@ -35,13 +35,16 @@ #include "directshowglobal.h" +#ifndef QT_NO_WIDGETS #include <QtGui/QPalette> #include <QtWidgets/QWidget> +#endif Vmr9VideoWindowControl::Vmr9VideoWindowControl(QObject *parent) : QVideoWindowControl(parent) - , m_filter(com_new<IBaseFilter>(CLSID_VideoMixingRenderer9, IID_IBaseFilter)) + , m_filter(com_new<IBaseFilter>(CLSID_VideoMixingRenderer9)) , m_windowId(0) + , m_windowColor(RGB(0, 0, 0)) , m_dirtyValues(0) , m_aspectRatioMode(Qt::KeepAspectRatio) , m_brightness(0) @@ -74,11 +77,13 @@ void Vmr9VideoWindowControl::setWinId(WId id) { m_windowId = id; +#ifndef QT_NO_WIDGETS if (QWidget *widget = QWidget::find(m_windowId)) { const QColor color = widget->palette().color(QPalette::Window); m_windowColor = RGB(color.red(), color.green(), color.blue()); } +#endif if (IVMRWindowlessControl9 *control = com_cast<IVMRWindowlessControl9>( m_filter, IID_IVMRWindowlessControl9)) { diff --git a/src/plugins/gstreamer/camerabin/camerabin.pro b/src/plugins/gstreamer/camerabin/camerabin.pro index 111dbccf0..80d992960 100644 --- a/src/plugins/gstreamer/camerabin/camerabin.pro +++ b/src/plugins/gstreamer/camerabin/camerabin.pro @@ -85,6 +85,10 @@ config_gstreamer_photography { DEFINES += GST_USE_UNSTABLE_API #prevents warnings because of unstable photography API } +config_gstreamer_encodingprofiles { + DEFINES += HAVE_GST_ENCODING_PROFILES +} + OTHER_FILES += \ camerabin.json diff --git a/src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp b/src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp index 2ff0bd8d0..f8137a3c9 100644 --- a/src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinaudioencoder.cpp @@ -33,7 +33,6 @@ #include "camerabinaudioencoder.h" #include "camerabincontainer.h" -#include <private/qgstcodecsinfo_p.h> #include <private/qgstutils_p.h> #include <QtCore/qdebug.h> @@ -41,8 +40,10 @@ QT_BEGIN_NAMESPACE CameraBinAudioEncoder::CameraBinAudioEncoder(QObject *parent) - :QAudioEncoderSettingsControl(parent), - m_codecs(QGstCodecsInfo::AudioEncoder) + :QAudioEncoderSettingsControl(parent) +#ifdef HAVE_GST_ENCODING_PROFILES + , m_codecs(QGstCodecsInfo::AudioEncoder) +#endif { } @@ -52,12 +53,21 @@ CameraBinAudioEncoder::~CameraBinAudioEncoder() QStringList CameraBinAudioEncoder::supportedAudioCodecs() const { +#ifdef HAVE_GST_ENCODING_PROFILES return m_codecs.supportedCodecs(); +#else + return QStringList(); +#endif } QString CameraBinAudioEncoder::codecDescription(const QString &codecName) const { +#ifdef HAVE_GST_ENCODING_PROFILES return m_codecs.codecDescription(codecName); +#else + Q_UNUSED(codecName) + return QString(); +#endif } QList<int> CameraBinAudioEncoder::supportedSampleRates(const QAudioEncoderSettings &, bool *) const @@ -96,6 +106,8 @@ void CameraBinAudioEncoder::resetActualSettings() m_actualAudioSettings = m_audioSettings; } +#ifdef HAVE_GST_ENCODING_PROFILES + GstEncodingProfile *CameraBinAudioEncoder::createProfile() { QString codec = m_actualAudioSettings.codec(); @@ -118,6 +130,8 @@ GstEncodingProfile *CameraBinAudioEncoder::createProfile() return profile; } +#endif + void CameraBinAudioEncoder::applySettings(GstElement *encoder) { GObjectClass * const objectClass = G_OBJECT_GET_CLASS(encoder); diff --git a/src/plugins/gstreamer/camerabin/camerabinaudioencoder.h b/src/plugins/gstreamer/camerabin/camerabinaudioencoder.h index caa4b7523..ef73467fa 100644 --- a/src/plugins/gstreamer/camerabin/camerabinaudioencoder.h +++ b/src/plugins/gstreamer/camerabin/camerabinaudioencoder.h @@ -42,10 +42,13 @@ #include <gst/gst.h> #include <gst/pbutils/pbutils.h> + +#ifdef HAVE_GST_ENCODING_PROFILES #include <gst/pbutils/encoding-profile.h> +#include <private/qgstcodecsinfo_p.h> +#endif #include <qaudioformat.h> -#include <private/qgstcodecsinfo_p.h> QT_BEGIN_NAMESPACE class CameraBinSession; @@ -76,7 +79,9 @@ public: void setActualAudioSettings(const QAudioEncoderSettings&); void resetActualSettings(); +#ifdef HAVE_GST_ENCODING_PROFILES GstEncodingProfile *createProfile(); +#endif void applySettings(GstElement *element); @@ -84,7 +89,9 @@ Q_SIGNALS: void settingsChanged(); private: +#ifdef HAVE_GST_ENCODING_PROFILES QGstCodecsInfo m_codecs; +#endif QAudioEncoderSettings m_actualAudioSettings; QAudioEncoderSettings m_audioSettings; diff --git a/src/plugins/gstreamer/camerabin/camerabincontainer.cpp b/src/plugins/gstreamer/camerabin/camerabincontainer.cpp index 8c31d20cd..f5b6900f9 100644 --- a/src/plugins/gstreamer/camerabin/camerabincontainer.cpp +++ b/src/plugins/gstreamer/camerabin/camerabincontainer.cpp @@ -39,8 +39,10 @@ QT_BEGIN_NAMESPACE CameraBinContainer::CameraBinContainer(QObject *parent) - :QMediaContainerControl(parent), - m_supportedContainers(QGstCodecsInfo::Muxer) + :QMediaContainerControl(parent) +#ifdef HAVE_GST_ENCODING_PROFILES + , m_supportedContainers(QGstCodecsInfo::Muxer) +#endif { //extension for containers hard to guess from mimetype m_fileExtensions["video/x-matroska"] = "mkv"; @@ -54,12 +56,21 @@ CameraBinContainer::CameraBinContainer(QObject *parent) QStringList CameraBinContainer::supportedContainers() const { +#ifdef HAVE_GST_ENCODING_PROFILES return m_supportedContainers.supportedCodecs(); +#else + return QStringList(); +#endif } QString CameraBinContainer::containerDescription(const QString &formatMimeType) const { +#ifdef HAVE_GST_ENCODING_PROFILES return m_supportedContainers.codecDescription(formatMimeType); +#else + Q_UNUSED(formatMimeType) + return QString(); +#endif } QString CameraBinContainer::containerFormat() const @@ -69,11 +80,13 @@ QString CameraBinContainer::containerFormat() const void CameraBinContainer::setContainerFormat(const QString &format) { +#ifdef HAVE_GST_ENCODING_PROFILES if (m_format != format) { m_format = format; m_actualFormat = format; emit settingsChanged(); } +#endif } QString CameraBinContainer::actualContainerFormat() const @@ -83,7 +96,9 @@ QString CameraBinContainer::actualContainerFormat() const void CameraBinContainer::setActualContainerFormat(const QString &containerFormat) { +#ifdef HAVE_GST_ENCODING_PROFILES m_actualFormat = containerFormat; +#endif } void CameraBinContainer::resetActualContainerFormat() @@ -91,6 +106,8 @@ void CameraBinContainer::resetActualContainerFormat() m_actualFormat = m_format; } +#ifdef HAVE_GST_ENCODING_PROFILES + GstEncodingContainerProfile *CameraBinContainer::createProfile() { GstCaps *caps; @@ -127,6 +144,8 @@ GstEncodingContainerProfile *CameraBinContainer::createProfile() return profile; } +#endif + /*! Suggest file extension for current container mimetype. */ diff --git a/src/plugins/gstreamer/camerabin/camerabincontainer.h b/src/plugins/gstreamer/camerabin/camerabincontainer.h index 2f5173388..8f2079535 100644 --- a/src/plugins/gstreamer/camerabin/camerabincontainer.h +++ b/src/plugins/gstreamer/camerabin/camerabincontainer.h @@ -41,9 +41,11 @@ #include <gst/gst.h> #include <gst/pbutils/pbutils.h> -#include <gst/pbutils/encoding-profile.h> +#ifdef HAVE_GST_ENCODING_PROFILES +#include <gst/pbutils/encoding-profile.h> #include <private/qgstcodecsinfo_p.h> +#endif QT_BEGIN_NAMESPACE @@ -66,7 +68,9 @@ public: QString suggestedFileExtension(const QString &containerFormat) const; +#ifdef HAVE_GST_ENCODING_PROFILES GstEncodingContainerProfile *createProfile(); +#endif Q_SIGNALS: void settingsChanged(); @@ -76,7 +80,9 @@ private: QString m_actualFormat; QMap<QString, QString> m_fileExtensions; +#ifdef HAVE_GST_ENCODING_PROFILES QGstCodecsInfo m_supportedContainers; +#endif }; QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp b/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp index 14b6c1297..e404065fc 100644 --- a/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinmetadata.cpp @@ -42,6 +42,8 @@ QT_BEGIN_NAMESPACE +#if GST_CHECK_VERSION(0,10,30) + static QVariant fromGStreamerOrientation(const QVariant &value) { // Note gstreamer tokens either describe the counter clockwise rotation of the @@ -58,6 +60,8 @@ static QVariant fromGStreamerOrientation(const QVariant &value) return 0; } +#endif + static QVariant toGStreamerOrientation(const QVariant &value) { switch (value.toInt()) { @@ -97,7 +101,9 @@ static const QGStreamerMetaDataKeys *qt_gstreamerMetaDataKeys() //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::SubTitle, 0, QVariant::String)); //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Author, 0, QVariant::String)); metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Comment, GST_TAG_COMMENT, QVariant::String)); +#if GST_CHECK_VERSION(0,10,31) metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Date, GST_TAG_DATE_TIME, QVariant::DateTime)); +#endif metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Description, GST_TAG_DESCRIPTION, QVariant::String)); //metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Category, 0, QVariant::String)); metadataKeys->append(QGStreamerMetaDataKey(QMediaMetaData::Genre, GST_TAG_GENRE, QVariant::String)); @@ -182,12 +188,14 @@ CameraBinMetaData::CameraBinMetaData(QObject *parent) QVariant CameraBinMetaData::metaData(const QString &key) const { +#if GST_CHECK_VERSION(0,10,30) if (key == QMediaMetaData::Orientation) { return fromGStreamerOrientation(m_values.value(QByteArray(GST_TAG_IMAGE_ORIENTATION))); } else if (key == QMediaMetaData::GPSSpeed) { const double metersPerSec = m_values.value(QByteArray(GST_TAG_GEO_LOCATION_MOVEMENT_SPEED)).toDouble(); return (metersPerSec * 3600) / 1000; } +#endif Q_FOREACH (const QGStreamerMetaDataKey &metadataKey, *qt_gstreamerMetaDataKeys()) { if (metadataKey.qtName == key) diff --git a/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp b/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp index 4154e1d65..ad0596a6e 100644 --- a/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinrecorder.cpp @@ -39,7 +39,6 @@ #include "camerabincontainer.h" #include <QtCore/QDebug> -#include <gst/pbutils/encoding-profile.h> QT_BEGIN_NAMESPACE @@ -131,6 +130,7 @@ qint64 CameraBinRecorder::duration() const void CameraBinRecorder::applySettings() { +#ifdef HAVE_GST_ENCODING_PROFILES CameraBinContainer *containerControl = m_session->mediaContainerControl(); CameraBinAudioEncoder *audioEncoderControl = m_session->audioEncodeControl(); CameraBinVideoEncoder *videoEncoderControl = m_session->videoEncodeControl(); @@ -172,8 +172,11 @@ void CameraBinRecorder::applySettings() } } } +#endif } +#ifdef HAVE_GST_ENCODING_PROFILES + GstEncodingContainerProfile *CameraBinRecorder::videoProfile() { GstEncodingContainerProfile *containerProfile = m_session->mediaContainerControl()->createProfile(); @@ -195,6 +198,8 @@ GstEncodingContainerProfile *CameraBinRecorder::videoProfile() return containerProfile; } +#endif + void CameraBinRecorder::setState(QMediaRecorder::State state) { if (m_state == state) diff --git a/src/plugins/gstreamer/camerabin/camerabinrecorder.h b/src/plugins/gstreamer/camerabin/camerabinrecorder.h index 959155520..ce0e85d40 100644 --- a/src/plugins/gstreamer/camerabin/camerabinrecorder.h +++ b/src/plugins/gstreamer/camerabin/camerabinrecorder.h @@ -37,7 +37,10 @@ #include <qmediarecordercontrol.h> #include "camerabinsession.h" + +#ifdef HAVE_GST_ENCODING_PROFILES #include <gst/pbutils/encoding-profile.h> +#endif QT_BEGIN_NAMESPACE @@ -61,7 +64,10 @@ public: qreal volume() const; void applySettings(); + +#ifdef HAVE_GST_ENCODING_PROFILES GstEncodingContainerProfile *videoProfile(); +#endif public slots: void setState(QMediaRecorder::State state); diff --git a/src/plugins/gstreamer/camerabin/camerabinservice.cpp b/src/plugins/gstreamer/camerabin/camerabinservice.cpp index a22301e2e..f0958bc51 100644 --- a/src/plugins/gstreamer/camerabin/camerabinservice.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinservice.cpp @@ -47,7 +47,6 @@ #include "camerabinflash.h" #include "camerabinfocus.h" #include "camerabinlocks.h" -#include "camerabinzoom.h" #endif #include "camerabinimagecapture.h" @@ -56,6 +55,7 @@ #include "camerabincapturedestination.h" #include "camerabinviewfindersettings.h" #include "camerabinviewfindersettings2.h" +#include "camerabinzoom.h" #include <private/qgstreamerbushelper_p.h> #include <private/qgstutils_p.h> @@ -226,10 +226,10 @@ QMediaControl *CameraBinService::requestControl(const char *name) if (qstrcmp(name, QCameraLocksControl_iid) == 0) return m_captureSession->cameraLocksControl(); +#endif if (qstrcmp(name, QCameraZoomControl_iid) == 0) return m_captureSession->cameraZoomControl(); -#endif if (qstrcmp(name, QCameraImageProcessingControl_iid) == 0) return m_captureSession->imageProcessingControl(); diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.cpp b/src/plugins/gstreamer/camerabin/camerabinsession.cpp index a0e9f753b..3dd200c54 100644 --- a/src/plugins/gstreamer/camerabin/camerabinsession.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinsession.cpp @@ -308,7 +308,7 @@ static GstCaps *resolutionToCaps(const QSize &resolution, if (frameRate > 0.0) { gint numerator; gint denominator; - gst_util_double_to_fraction(frameRate, &numerator, &denominator); + qt_gst_util_double_to_fraction(frameRate, &numerator, &denominator); gst_caps_set_simple( caps, @@ -404,7 +404,7 @@ void CameraBinSession::setupCaptureResolution() if (!qFuzzyIsNull(viewfinderFrameRate)) { int n, d; - gst_util_double_to_fraction(viewfinderFrameRate, &n, &d); + qt_gst_util_double_to_fraction(viewfinderFrameRate, &n, &d); g_object_set(G_OBJECT(m_videoSrc), "fps-n", n, NULL); g_object_set(G_OBJECT(m_videoSrc), "fps-d", d, NULL); } @@ -798,12 +798,14 @@ void CameraBinSession::start() m_recorderControl->applySettings(); +#ifdef HAVE_GST_ENCODING_PROFILES GstEncodingContainerProfile *profile = m_recorderControl->videoProfile(); g_object_set (G_OBJECT(m_camerabin), "video-profile", profile, NULL); gst_encoding_profile_unref(profile); +#endif setAudioCaptureCaps(); @@ -1065,13 +1067,38 @@ bool CameraBinSession::processBusMessage(const QGstreamerMessage &message) return false; } +QString CameraBinSession::currentContainerFormat() const +{ + if (!m_muxer) + return QString(); + + QString format; + + if (GstPad *srcPad = gst_element_get_static_pad(m_muxer, "src")) { + if (GstCaps *caps = qt_gst_pad_get_caps(srcPad)) { + gchar *capsString = gst_caps_to_string(caps); + format = QString::fromLatin1(capsString); + if (capsString) + g_free(capsString); + gst_caps_unref(caps); + } + gst_object_unref(GST_OBJECT(srcPad)); + } + + return format; +} + void CameraBinSession::recordVideo() { + QString format = currentContainerFormat(); + if (format.isEmpty()) + format = m_mediaContainerControl->actualContainerFormat(); + const QString actualFileName = m_mediaStorageLocation.generateFileName(m_sink.isLocalFile() ? m_sink.toLocalFile() : m_sink.toString(), QMediaStorageLocation::Movies, QLatin1String("clip_"), - m_mediaContainerControl->suggestedFileExtension(m_mediaContainerControl->actualContainerFormat())); + m_mediaContainerControl->suggestedFileExtension(format)); m_recordingActive = true; m_actualSink = QUrl::fromLocalFile(actualFileName); @@ -1433,14 +1460,28 @@ void CameraBinSession::elementAdded(GstBin *, GstElement *element, CameraBinSess g_signal_connect(G_OBJECT(element), "element-removed", G_CALLBACK(elementRemoved), session); } else if (!factory) { // no-op +#if GST_CHECK_VERSION(0,10,31) } else if (gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_AUDIO_ENCODER)) { +#else + } else if (strstr(gst_element_factory_get_klass(factory), "Encoder/Audio") != NULL) { +#endif session->m_audioEncoder = element; session->m_audioEncodeControl->applySettings(element); +#if GST_CHECK_VERSION(0,10,31) } else if (gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_VIDEO_ENCODER)) { +#else + } else if (strstr(gst_element_factory_get_klass(factory), "Encoder/Video") != NULL) { +#endif session->m_videoEncoder = element; session->m_videoEncodeControl->applySettings(element); +#if GST_CHECK_VERSION(0,10,31) + } else if (gst_element_factory_list_is_type(factory, GST_ELEMENT_FACTORY_TYPE_MUXER)) { +#else + } else if (strstr(gst_element_factory_get_klass(factory), "Muxer") != NULL) { +#endif + session->m_muxer = element; } } @@ -1450,6 +1491,8 @@ void CameraBinSession::elementRemoved(GstBin *, GstElement *element, CameraBinSe session->m_audioEncoder = 0; else if (element == session->m_videoEncoder) session->m_videoEncoder = 0; + else if (element == session->m_muxer) + session->m_muxer = 0; } QT_END_NAMESPACE diff --git a/src/plugins/gstreamer/camerabin/camerabinsession.h b/src/plugins/gstreamer/camerabin/camerabinsession.h index 553c2a1ad..1c5c9899d 100644 --- a/src/plugins/gstreamer/camerabin/camerabinsession.h +++ b/src/plugins/gstreamer/camerabin/camerabinsession.h @@ -195,6 +195,8 @@ private: void updateSupportedViewfinderSettings(); static void updateBusyStatus(GObject *o, GParamSpec *p, gpointer d); + QString currentContainerFormat() const; + static void elementAdded(GstBin *bin, GstElement *element, CameraBinSession *session); static void elementRemoved(GstBin *bin, GstElement *element, CameraBinSession *session); diff --git a/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp b/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp index f80ba4a41..2d53af1fb 100644 --- a/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp +++ b/src/plugins/gstreamer/camerabin/camerabinvideoencoder.cpp @@ -41,9 +41,11 @@ QT_BEGIN_NAMESPACE CameraBinVideoEncoder::CameraBinVideoEncoder(CameraBinSession *session) - :QVideoEncoderSettingsControl(session), - m_session(session), - m_codecs(QGstCodecsInfo::VideoEncoder) + :QVideoEncoderSettingsControl(session) + , m_session(session) +#ifdef HAVE_GST_ENCODING_PROFILES + , m_codecs(QGstCodecsInfo::VideoEncoder) +#endif { } @@ -81,12 +83,21 @@ QList< qreal > CameraBinVideoEncoder::supportedFrameRates(const QVideoEncoderSet QStringList CameraBinVideoEncoder::supportedVideoCodecs() const { +#ifdef HAVE_GST_ENCODING_PROFILES return m_codecs.supportedCodecs(); +#else + return QStringList(); +#endif } QString CameraBinVideoEncoder::videoCodecDescription(const QString &codecName) const { +#ifdef HAVE_GST_ENCODING_PROFILES return m_codecs.codecDescription(codecName); +#else + Q_UNUSED(codecName) + return QString(); +#endif } QVideoEncoderSettings CameraBinVideoEncoder::videoSettings() const @@ -150,6 +161,8 @@ QPair<int,int> CameraBinVideoEncoder::rateAsRational(qreal frameRate) const return QPair<int,int>(); } +#ifdef HAVE_GST_ENCODING_PROFILES + GstEncodingProfile *CameraBinVideoEncoder::createProfile() { QString codec = m_actualVideoSettings.codec(); @@ -176,6 +189,8 @@ GstEncodingProfile *CameraBinVideoEncoder::createProfile() return (GstEncodingProfile *)profile; } +#endif + void CameraBinVideoEncoder::applySettings(GstElement *encoder) { GObjectClass * const objectClass = G_OBJECT_GET_CLASS(encoder); diff --git a/src/plugins/gstreamer/camerabin/camerabinvideoencoder.h b/src/plugins/gstreamer/camerabin/camerabinvideoencoder.h index 9eebf28b8..532376ac6 100644 --- a/src/plugins/gstreamer/camerabin/camerabinvideoencoder.h +++ b/src/plugins/gstreamer/camerabin/camerabinvideoencoder.h @@ -42,8 +42,11 @@ #include <gst/gst.h> #include <gst/pbutils/pbutils.h> + +#ifdef HAVE_GST_ENCODING_PROFILES #include <gst/pbutils/encoding-profile.h> #include <private/qgstcodecsinfo_p.h> +#endif QT_BEGIN_NAMESPACE @@ -74,7 +77,9 @@ public: void setActualVideoSettings(const QVideoEncoderSettings&); void resetActualSettings(); +#ifdef HAVE_GST_ENCODING_PROFILES GstEncodingProfile *createProfile(); +#endif void applySettings(GstElement *encoder); @@ -84,7 +89,9 @@ Q_SIGNALS: private: CameraBinSession *m_session; +#ifdef HAVE_GST_ENCODING_PROFILES QGstCodecsInfo m_codecs; +#endif QVideoEncoderSettings m_actualVideoSettings; QVideoEncoderSettings m_videoSettings; diff --git a/src/plugins/gstreamer/gstreamer.pro b/src/plugins/gstreamer/gstreamer.pro index 0ff35101e..5fb8f83c6 100644 --- a/src/plugins/gstreamer/gstreamer.pro +++ b/src/plugins/gstreamer/gstreamer.pro @@ -2,12 +2,9 @@ TEMPLATE = subdirs SUBDIRS += \ audiodecoder \ + camerabin \ mediaplayer \ mediacapture -config_gstreamer_encodingprofiles { - SUBDIRS += camerabin -} - OTHER_FILES += \ gstreamer.json diff --git a/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp b/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp index 8cbdb6717..ba21ff307 100644 --- a/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp +++ b/src/plugins/gstreamer/mediacapture/qgstreamercaptureserviceplugin.cpp @@ -88,7 +88,7 @@ QList<QByteArray> QGstreamerCaptureServicePlugin::devices(const QByteArray &serv QString QGstreamerCaptureServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device) { - return service == Q_MEDIASERVICE_CAMERA ? QGstUtils::cameraDescription(deviceName) : QString(); + return service == Q_MEDIASERVICE_CAMERA ? QGstUtils::cameraDescription(device) : QString(); } QVariant QGstreamerCaptureServicePlugin::deviceProperty(const QByteArray &service, const QByteArray &device, const QByteArray &property) diff --git a/src/plugins/pulseaudio/qaudioinput_pulse.cpp b/src/plugins/pulseaudio/qaudioinput_pulse.cpp index 1a34d594d..77b438ff9 100644 --- a/src/plugins/pulseaudio/qaudioinput_pulse.cpp +++ b/src/plugins/pulseaudio/qaudioinput_pulse.cpp @@ -150,6 +150,7 @@ QPulseAudioInput::QPulseAudioInput(const QByteArray &device) , m_errorState(QAudio::NoError) , m_deviceState(QAudio::StoppedState) , m_volume(qreal(1.0f)) + , m_customVolumeRequired(false) , m_pullMode(true) , m_opened(false) , m_bytesAvailable(0) @@ -355,7 +356,8 @@ bool QPulseAudioInput::open() if (actualBufferAttr->tlength != (uint32_t)-1) m_bufferSize = actualBufferAttr->tlength; - setPulseVolume(); + if (m_customVolumeRequired) + setPulseVolume(); pulseEngine->unlock(); @@ -568,6 +570,7 @@ void QPulseAudioInput::setVolume(qreal vol) if (vol >= 0.0 && vol <= 1.0) { QPulseAudioEngine *pulseEngine = QPulseAudioEngine::instance(); pulseEngine->lock(); + m_customVolumeRequired = true; if (!qFuzzyCompare(m_volume, vol)) { m_volume = vol; if (m_opened) { diff --git a/src/plugins/pulseaudio/qaudioinput_pulse.h b/src/plugins/pulseaudio/qaudioinput_pulse.h index 6963a2419..7b898c480 100644 --- a/src/plugins/pulseaudio/qaudioinput_pulse.h +++ b/src/plugins/pulseaudio/qaudioinput_pulse.h @@ -100,6 +100,7 @@ public: QAudio::Error m_errorState; QAudio::State m_deviceState; qreal m_volume; + bool m_customVolumeRequired; pa_cvolume m_chVolume; private slots: diff --git a/src/plugins/winrt/qwinrtcameracontrol.cpp b/src/plugins/winrt/qwinrtcameracontrol.cpp index 7a926ad60..19b718cdd 100644 --- a/src/plugins/winrt/qwinrtcameracontrol.cpp +++ b/src/plugins/winrt/qwinrtcameracontrol.cpp @@ -517,6 +517,7 @@ public: ComPtr<MediaSink> mediaSink; ComPtr<IFocusControl> focusControl; ComPtr<IRegionsOfInterestControl> regionsOfInterestControl; + ComPtr<IAsyncAction> focusOperation; QPointer<QWinRTCameraVideoRendererControl> videoRenderer; QPointer<QWinRTVideoDeviceSelectorControl> videoDeviceSelector; @@ -620,6 +621,11 @@ void QWinRTCameraControl::setState(QCamera::State state) case QCamera::UnloadedState: { // Stop the camera if it is running (transition to LoadedState) if (d->status == QCamera::ActiveStatus) { + HRESULT hr; + if (d->focusOperation) { + hr = QWinRTFunctions::await(d->focusOperation); + Q_ASSERT_SUCCEEDED(hr); + } if (d->framesMapped > 0) { qWarning("%d QVideoFrame(s) mapped when closing down camera. Camera will wait for unmap before closing down.", d->framesMapped); @@ -840,9 +846,9 @@ HRESULT QWinRTCameraControl::initialize() return E_FAIL; } - if (d->videoDeviceSelector->cameraPosition(deviceName) == QCamera::FrontFace) - d->videoRenderer->setScanLineDirection(QVideoSurfaceFormat::BottomToTop); - + const QCamera::Position position = d->videoDeviceSelector->cameraPosition(deviceName); + d->videoRenderer->setScanLineDirection(position == QCamera::BackFace ? QVideoSurfaceFormat::TopToBottom + : QVideoSurfaceFormat::BottomToTop); ComPtr<IMediaCaptureInitializationSettings> settings; hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Media_Capture_MediaCaptureInitializationSettings).Get(), &settings); @@ -1150,14 +1156,26 @@ bool QWinRTCameraControl::setFocusPoint(const QPointF &focusPoint) bool QWinRTCameraControl::focus() { Q_D(QWinRTCameraControl); - if (!d->focusControl) + HRESULT hr; + AsyncStatus status = AsyncStatus::Completed; + if (d->focusOperation) { + ComPtr<IAsyncInfo> info; + hr = d->focusOperation.As(&info); + Q_ASSERT_SUCCEEDED(hr); + info->get_Status(&status); + } + + if (!d->focusControl || status == AsyncStatus::Started) return false; - ComPtr<IAsyncAction> op; - HRESULT hr = d->focusControl->FocusAsync(&op); - if (HRESULT_CODE(hr) == ERROR_OPERATION_IN_PROGRESS) - return true; + + hr = d->focusControl->FocusAsync(&d->focusOperation); + const long errorCode = HRESULT_CODE(hr); + if (errorCode == ERROR_OPERATION_IN_PROGRESS + || errorCode == ERROR_WRITE_PROTECT) { + return false; + } Q_ASSERT_SUCCEEDED(hr); - hr = QWinRTFunctions::await(op, QWinRTFunctions::ProcessThreadEvents); + hr = QWinRTFunctions::await(d->focusOperation, QWinRTFunctions::ProcessThreadEvents); Q_ASSERT_SUCCEEDED(hr); return hr == S_OK; } @@ -1184,6 +1202,8 @@ bool QWinRTCameraControl::lockFocus() Q_ASSERT_SUCCEEDED(hr); ComPtr<IAsyncAction> op; hr = focusControl2->LockAsync(&op); + if (HRESULT_CODE(hr) == ERROR_WRITE_PROTECT) + return false; Q_ASSERT_SUCCEEDED(hr); return QWinRTFunctions::await(op) == S_OK; } @@ -1198,6 +1218,8 @@ bool QWinRTCameraControl::unlockFocus() Q_ASSERT_SUCCEEDED(hr); ComPtr<IAsyncAction> op; hr = focusControl2->UnlockAsync(&op); + if (HRESULT_CODE(hr) == ERROR_WRITE_PROTECT) + return false; Q_ASSERT_SUCCEEDED(hr); return QWinRTFunctions::await(op) == S_OK; } diff --git a/src/plugins/winrt/qwinrtcameralockscontrol.cpp b/src/plugins/winrt/qwinrtcameralockscontrol.cpp index e429c5ff1..8528d16fb 100644 --- a/src/plugins/winrt/qwinrtcameralockscontrol.cpp +++ b/src/plugins/winrt/qwinrtcameralockscontrol.cpp @@ -66,13 +66,14 @@ QCamera::LockStatus QWinRTCameraLocksControl::lockStatus(QCamera::LockType lock) void QWinRTCameraLocksControl::searchAndLock(QCamera::LockTypes locks) { - if (locks.testFlag(QCamera::LockFocus)) { + QWinRTCameraControl *cameraControl = qobject_cast<QWinRTCameraControl *>(parent()); + Q_ASSERT(cameraControl); + if (cameraControl->state() != QCamera::ActiveState) + return; + else if (locks.testFlag(QCamera::LockFocus)) QMetaObject::invokeMethod(this, "searchAndLockFocus", Qt::QueuedConnection); - } else { - QWinRTCameraControl *cameraControl = qobject_cast<QWinRTCameraControl *>(parent()); - Q_ASSERT(cameraControl); + else cameraControl->emitError(QCamera::InvalidRequestError, QStringLiteral("Unsupported camera lock type.")); - } } void QWinRTCameraLocksControl::unlock(QCamera::LockTypes locks) @@ -104,10 +105,10 @@ void QWinRTCameraLocksControl::searchAndLockFocus() } else { m_focusLockStatus = QCamera::Searching; emit lockStatusChanged(QCamera::LockFocus, m_focusLockStatus, QCamera::LockAcquired); - cameraControl->focus(); - cameraControl->lockFocus(); - m_focusLockStatus = QCamera::Locked; - emit lockStatusChanged(QCamera::LockFocus, m_focusLockStatus, QCamera::LockAcquired); + if (cameraControl->focus()) { + m_focusLockStatus = cameraControl->lockFocus() ? QCamera::Locked : QCamera::Unlocked; + emit lockStatusChanged(QCamera::LockFocus, m_focusLockStatus, QCamera::LockAcquired); + } } } @@ -117,8 +118,7 @@ void QWinRTCameraLocksControl::unlockFocus() return; QWinRTCameraControl *cameraControl = qobject_cast<QWinRTCameraControl *>(parent()); Q_ASSERT(cameraControl); - cameraControl->unlockFocus(); - m_focusLockStatus = QCamera::Unlocked; + m_focusLockStatus = cameraControl->unlockFocus() ? QCamera::Unlocked : QCamera::Locked; emit lockStatusChanged(QCamera::LockFocus, m_focusLockStatus, QCamera::UserRequest); } diff --git a/src/plugins/wmf/player/mfevrvideowindowcontrol.cpp b/src/plugins/wmf/player/mfevrvideowindowcontrol.cpp new file mode 100644 index 000000000..404f38125 --- /dev/null +++ b/src/plugins/wmf/player/mfevrvideowindowcontrol.cpp @@ -0,0 +1,85 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "mfevrvideowindowcontrol.h" + +#include <qdebug.h> + +MFEvrVideoWindowControl::MFEvrVideoWindowControl(QObject *parent) + : EvrVideoWindowControl(parent) + , m_currentActivate(NULL) + , m_evrSink(NULL) +{ +} + +MFEvrVideoWindowControl::~MFEvrVideoWindowControl() +{ + clear(); +} + +void MFEvrVideoWindowControl::clear() +{ + setEvr(NULL); + + if (m_evrSink) + m_evrSink->Release(); + if (m_currentActivate) { + m_currentActivate->ShutdownObject(); + m_currentActivate->Release(); + } + m_evrSink = NULL; + m_currentActivate = NULL; +} + +IMFActivate* MFEvrVideoWindowControl::createActivate() +{ + clear(); + + if (FAILED(MFCreateVideoRendererActivate(0, &m_currentActivate))) { + qWarning() << "Failed to create evr video renderer activate!"; + return NULL; + } + if (FAILED(m_currentActivate->ActivateObject(IID_IMFMediaSink, (LPVOID*)(&m_evrSink)))) { + qWarning() << "Failed to activate evr media sink!"; + return NULL; + } + if (!setEvr(m_evrSink)) + return NULL; + + return m_currentActivate; +} + +void MFEvrVideoWindowControl::releaseActivate() +{ + clear(); +} diff --git a/src/plugins/wmf/player/mfevrvideowindowcontrol.h b/src/plugins/wmf/player/mfevrvideowindowcontrol.h new file mode 100644 index 000000000..e5a38f27d --- /dev/null +++ b/src/plugins/wmf/player/mfevrvideowindowcontrol.h @@ -0,0 +1,57 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 http://www.qt.io/terms-conditions. For further +** information use the contact form at http://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 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MFEVRVIDEOWINDOWCONTROL_H +#define MFEVRVIDEOWINDOWCONTROL_H + +#include "evrvideowindowcontrol.h" + +QT_USE_NAMESPACE + +class MFEvrVideoWindowControl : public EvrVideoWindowControl +{ +public: + MFEvrVideoWindowControl(QObject *parent = 0); + ~MFEvrVideoWindowControl(); + + IMFActivate* createActivate(); + void releaseActivate(); + +private: + void clear(); + + IMFActivate *m_currentActivate; + IMFMediaSink *m_evrSink; +}; + +#endif // MFEVRVIDEOWINDOWCONTROL_H diff --git a/src/plugins/wmf/player/mfplayerservice.cpp b/src/plugins/wmf/player/mfplayerservice.cpp index 4e88b0498..99c6abb3e 100644 --- a/src/plugins/wmf/player/mfplayerservice.cpp +++ b/src/plugins/wmf/player/mfplayerservice.cpp @@ -36,9 +36,7 @@ #include <QtCore/qdebug.h> #include "mfplayercontrol.h" -#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR) -#include "evr9videowindowcontrol.h" -#endif +#include "mfevrvideowindowcontrol.h" #include "mfvideorenderercontrol.h" #include "mfaudioendpointcontrol.h" #include "mfaudioprobecontrol.h" @@ -50,9 +48,7 @@ MFPlayerService::MFPlayerService(QObject *parent) : QMediaService(parent) , m_session(0) -#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR) , m_videoWindowControl(0) -#endif , m_videoRendererControl(0) { m_audioEndpointControl = new MFAudioEndpointControl(this); @@ -65,10 +61,8 @@ MFPlayerService::~MFPlayerService() { m_session->close(); -#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR) if (m_videoWindowControl) delete m_videoWindowControl; -#endif if (m_videoRendererControl) delete m_videoRendererControl; @@ -85,21 +79,15 @@ QMediaControl* MFPlayerService::requestControl(const char *name) } else if (qstrcmp(name, QMetaDataReaderControl_iid) == 0) { return m_metaDataControl; } else if (qstrcmp(name, QVideoRendererControl_iid) == 0) { -#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR) if (!m_videoRendererControl && !m_videoWindowControl) { -#else - if (!m_videoRendererControl) { -#endif m_videoRendererControl = new MFVideoRendererControl; return m_videoRendererControl; } -#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR) } else if (qstrcmp(name, QVideoWindowControl_iid) == 0) { if (!m_videoRendererControl && !m_videoWindowControl) { - m_videoWindowControl = new Evr9VideoWindowControl; + m_videoWindowControl = new MFEvrVideoWindowControl; return m_videoWindowControl; } -#endif } else if (qstrcmp(name,QMediaAudioProbeControl_iid) == 0) { if (m_session) { MFAudioProbeControl *probe = new MFAudioProbeControl(this); @@ -129,12 +117,10 @@ void MFPlayerService::releaseControl(QMediaControl *control) delete m_videoRendererControl; m_videoRendererControl = 0; return; -#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR) } else if (control == m_videoWindowControl) { delete m_videoWindowControl; m_videoWindowControl = 0; return; -#endif } MFAudioProbeControl* audioProbe = qobject_cast<MFAudioProbeControl*>(control); @@ -164,12 +150,10 @@ MFVideoRendererControl* MFPlayerService::videoRendererControl() const return m_videoRendererControl; } -#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR) -Evr9VideoWindowControl* MFPlayerService::videoWindowControl() const +MFEvrVideoWindowControl* MFPlayerService::videoWindowControl() const { return m_videoWindowControl; } -#endif MFMetaDataControl* MFPlayerService::metaDataControl() const { diff --git a/src/plugins/wmf/player/mfplayerservice.h b/src/plugins/wmf/player/mfplayerservice.h index 62eb6b640..b3db70799 100644 --- a/src/plugins/wmf/player/mfplayerservice.h +++ b/src/plugins/wmf/player/mfplayerservice.h @@ -48,9 +48,7 @@ QT_END_NAMESPACE QT_USE_NAMESPACE -#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR) -class Evr9VideoWindowControl; -#endif +class MFEvrVideoWindowControl; class MFAudioEndpointControl; class MFVideoRendererControl; class MFPlayerControl; @@ -69,18 +67,14 @@ public: MFAudioEndpointControl* audioEndpointControl() const; MFVideoRendererControl* videoRendererControl() const; -#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR) - Evr9VideoWindowControl* videoWindowControl() const; -#endif + MFEvrVideoWindowControl* videoWindowControl() const; MFMetaDataControl* metaDataControl() const; private: MFPlayerSession *m_session; MFVideoRendererControl *m_videoRendererControl; MFAudioEndpointControl *m_audioEndpointControl; -#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR) - Evr9VideoWindowControl *m_videoWindowControl; -#endif + MFEvrVideoWindowControl *m_videoWindowControl; MFPlayerControl *m_player; MFMetaDataControl *m_metaDataControl; }; diff --git a/src/plugins/wmf/player/mfplayersession.cpp b/src/plugins/wmf/player/mfplayersession.cpp index 283853def..e4c498b76 100644 --- a/src/plugins/wmf/player/mfplayersession.cpp +++ b/src/plugins/wmf/player/mfplayersession.cpp @@ -43,9 +43,7 @@ #include <QtCore/qbuffer.h> #include "mfplayercontrol.h" -#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR) -#include "evr9videowindowcontrol.h" -#endif +#include "mfevrvideowindowcontrol.h" #include "mfvideorenderercontrol.h" #include "mfaudioendpointcontrol.h" @@ -140,10 +138,8 @@ void MFPlayerSession::close() if (m_playerService->videoRendererControl()) { m_playerService->videoRendererControl()->releaseActivate(); -#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR) } else if (m_playerService->videoWindowControl()) { m_playerService->videoWindowControl()->releaseActivate(); -#endif } if (m_session) @@ -404,10 +400,8 @@ IMFTopologyNode* MFPlayerSession::addOutputNode(IMFStreamDescriptor *streamDesc, mediaType = Video; if (m_playerService->videoRendererControl()) { activate = m_playerService->videoRendererControl()->createActivate(); -#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR) } else if (m_playerService->videoWindowControl()) { activate = m_playerService->videoWindowControl()->createActivate(); -#endif } else { qWarning() << "no videoWindowControl or videoRendererControl, unable to add output node for video data"; } @@ -1580,13 +1574,11 @@ void MFPlayerSession::handleSessionEvent(IMFMediaEvent *sessionEvent) } updatePendingCommands(CmdStart); -#if defined(HAVE_WIDGETS) && !defined(Q_WS_SIMULATOR) // playback started, we can now set again the procAmpValues if they have been // changed previously (these are lost when loading a new media) if (m_playerService->videoWindowControl()) { - m_playerService->videoWindowControl()->setProcAmpValues(); + m_playerService->videoWindowControl()->applyImageControls(); } -#endif break; case MESessionStopped: if (m_status != QMediaPlayer::EndOfMedia) { diff --git a/src/plugins/wmf/player/mfplayersession.h b/src/plugins/wmf/player/mfplayersession.h index effb36fa2..1d136ba55 100644 --- a/src/plugins/wmf/player/mfplayersession.h +++ b/src/plugins/wmf/player/mfplayersession.h @@ -57,7 +57,7 @@ QT_USE_NAMESPACE class SourceResolver; #ifndef Q_WS_SIMULATOR -class Evr9VideoWindowControl; +class EvrVideoWindowControl; #endif class MFAudioEndpointControl; class MFVideoRendererControl; diff --git a/src/plugins/wmf/player/player.pri b/src/plugins/wmf/player/player.pri index dd5c9dc12..c24370eea 100644 --- a/src/plugins/wmf/player/player.pri +++ b/src/plugins/wmf/player/player.pri @@ -12,7 +12,8 @@ HEADERS += \ $$PWD/mfaudioendpointcontrol.h \ $$PWD/mfmetadatacontrol.h \ $$PWD/mfaudioprobecontrol.h \ - $$PWD/mfvideoprobecontrol.h + $$PWD/mfvideoprobecontrol.h \ + $$PWD/mfevrvideowindowcontrol.h SOURCES += \ $$PWD/mfplayerservice.cpp \ @@ -22,9 +23,7 @@ SOURCES += \ $$PWD/mfaudioendpointcontrol.cpp \ $$PWD/mfmetadatacontrol.cpp \ $$PWD/mfaudioprobecontrol.cpp \ - $$PWD/mfvideoprobecontrol.cpp + $$PWD/mfvideoprobecontrol.cpp \ + $$PWD/mfevrvideowindowcontrol.cpp -qtHaveModule(widgets):!simulator { - HEADERS += $$PWD/evr9videowindowcontrol.h - SOURCES += $$PWD/evr9videowindowcontrol.cpp -} +include($$PWD/../../common/evr.pri) diff --git a/src/plugins/wmf/wmf.pro b/src/plugins/wmf/wmf.pro index 60fc3f641..68a777f37 100644 --- a/src/plugins/wmf/wmf.pro +++ b/src/plugins/wmf/wmf.pro @@ -1,9 +1,6 @@ TARGET = wmfengine QT += multimedia-private network -qtHaveModule(widgets) { - QT += multimediawidgets-private - DEFINES += HAVE_WIDGETS -} + win32:!qtHaveModule(opengl) { LIBS_PRIVATE += -lgdi32 -luser32 } @@ -37,15 +34,14 @@ contains(QT_CONFIG, angle)|contains(QT_CONFIG, dynamicgl) { QT += gui-private HEADERS += \ - evrcustompresenter.h \ - evrd3dpresentengine.h + $$PWD/evrcustompresenter.h \ + $$PWD/evrd3dpresentengine.h SOURCES += \ - evrcustompresenter.cpp \ - evrd3dpresentengine.cpp + $$PWD/evrcustompresenter.cpp \ + $$PWD/evrd3dpresentengine.cpp } - include (player/player.pri) include (decoder/decoder.pri) diff --git a/tests/auto/integration/qmediaplayerbackend/BLACKLIST b/tests/auto/integration/qmediaplayerbackend/BLACKLIST index dd6dd14b8..b9907f305 100644 --- a/tests/auto/integration/qmediaplayerbackend/BLACKLIST +++ b/tests/auto/integration/qmediaplayerbackend/BLACKLIST @@ -8,16 +8,13 @@ windows 64bit developer-build [construction] opensuse-13.1 64bit -redhatenterpriselinuxworkstation-6.6 [loadMedia] opensuse-13.1 64bit -redhatenterpriselinuxworkstation-6.6 windows 64bit developer-build [unloadMedia] opensuse-13.1 64bit -redhatenterpriselinuxworkstation-6.6 windows 64bit developer-build [playPauseStop] @@ -28,27 +25,34 @@ windows 64bit developer-build [processEOS] opensuse-13.1 64bit -redhatenterpriselinuxworkstation-6.6 windows 64bit developer-build [deleteLaterAtEOS] opensuse-13.1 64bit -redhatenterpriselinuxworkstation-6.6 windows 64bit developer-build [volumeAndMuted] opensuse-13.1 64bit -redhatenterpriselinuxworkstation-6.6 [volumeAcrossFiles] opensuse-13.1 64bit -redhatenterpriselinuxworkstation-6.6 [initialVolume] opensuse-13.1 64bit -redhatenterpriselinuxworkstation-6.6 windows 64bit developer-build [playlist] opensuse-13.1 64bit redhatenterpriselinuxworkstation-6.6 + +[seekPauseSeek] +redhatenterpriselinuxworkstation-6.6 + +[subsequentPlayback] +redhatenterpriselinuxworkstation-6.6 + +[probes] +redhatenterpriselinuxworkstation-6.6 + +[surfaceTest] +redhatenterpriselinuxworkstation-6.6 |