diff options
author | Lars Knoll <lars.knoll@qt.io> | 2020-12-18 08:54:44 +0100 |
---|---|---|
committer | Lars Knoll <lars.knoll@qt.io> | 2021-01-20 19:14:09 +0000 |
commit | aa441d63a1ed0843f4632da2d0a97a7b8bb24b43 (patch) | |
tree | 0059466afbde487245696891431d4cfbc26ee557 /src | |
parent | 5acdceb51f18e46d31ae3a99844a751c6742c8dc (diff) | |
download | qtmultimedia-aa441d63a1ed0843f4632da2d0a97a7b8bb24b43.tar.gz |
Remove the DirectShow backend
It's been deprecated by Microsoft since quite some time.
We should only have one backend on Windows, and then WMF
seems to be the correct one. WMF is missing features
like Camera, so some additional implementation work on
WMF will be required.
Change-Id: I5c3db4020b130efa78575c9da116a8ae6c34f7a1
Reviewed-by: Doris Verria <doris.verria@qt.io>
Reviewed-by: Lars Knoll <lars.knoll@qt.io>
Diffstat (limited to 'src')
80 files changed, 0 insertions, 14838 deletions
diff --git a/src/multimedia/configure.json b/src/multimedia/configure.json index 8c851e012..8cec0acb1 100644 --- a/src/multimedia/configure.json +++ b/src/multimedia/configure.json @@ -10,7 +10,6 @@ "options": { "alsa": "boolean", "evr": { "type": "boolean" }, - "directshow": { "type": "boolean" }, "wmf": { "type": "boolean" }, "gstreamer": { "type": "optionalString", "values": [ "no", "yes" ] }, "pulseaudio": "boolean" @@ -32,13 +31,6 @@ { "libs": "-framework AVFoundation -framework Foundation" } ] }, - "directshow": { - "label": "DirectShow", - "test": "directshow", - "sources": [ - { "libs": "-lstrmiids -ldmoguids -luuid -lmsdmo -lole32 -loleaut32" } - ] - }, "gstreamer_1_0": { "label": "GStreamer 1.0", "export": "gstreamer", @@ -131,11 +123,6 @@ "label": "wmsdk.h", "type": "compile", "test": "wmsdk" - }, - "wshellitem": { - "label": "WShellItem", - "type": "compile", - "test": "wshellitem" } }, @@ -151,11 +138,6 @@ "condition": "libs.avfoundation", "output": [ "feature", "privateFeature" ] }, - "directshow": { - "label": "DirectShow", - "condition": "config.win32 && libs.directshow", - "output": [ "feature", "privateFeature" ] - }, "evr": { "label": "evr.h", "condition": "config.win32 && tests.evr", @@ -219,11 +201,6 @@ "condition": "config.win32 && tests.wmsdk", "output": [ "privateFeature" ] }, - "wshellitem": { - "label": "WShellItem", - "condition": "config.win32 && features.directshow && tests.wshellitem", - "output": [ "feature", "privateFeature" ] - }, "wmf": { "label": "Windows Media Foundation", "condition": "config.win32 && libs.wmf", @@ -244,7 +221,6 @@ "pulseaudio", "mmrenderer", "avfoundation", - "directshow", "wmf" ] } diff --git a/src/plugins/directshow/camera/camera.pri b/src/plugins/directshow/camera/camera.pri deleted file mode 100644 index 3be1acc49..000000000 --- a/src/plugins/directshow/camera/camera.pri +++ /dev/null @@ -1,37 +0,0 @@ -INCLUDEPATH += $$PWD - -win32: DEFINES += _CRT_SECURE_NO_WARNINGS - -HEADERS += \ - $$PWD/dscameraservice.h \ - $$PWD/dscameracontrol.h \ - $$PWD/dsvideorenderer.h \ - $$PWD/dsvideodevicecontrol.h \ - $$PWD/dsimagecapturecontrol.h \ - $$PWD/dscamerasession.h \ - $$PWD/directshowcameraglobal.h \ - $$PWD/dscameraviewfindersettingscontrol.h \ - $$PWD/dscameraimageprocessingcontrol.h \ - $$PWD/directshowcameraexposurecontrol.h \ - $$PWD/directshowcameracapturedestinationcontrol.h \ - $$PWD/directshowcameracapturebufferformatcontrol.h \ - $$PWD/directshowcamerazoomcontrol.h \ - $$PWD/directshowcameraimageencodercontrol.h - -SOURCES += \ - $$PWD/dscameraservice.cpp \ - $$PWD/dscameracontrol.cpp \ - $$PWD/dsvideorenderer.cpp \ - $$PWD/dsvideodevicecontrol.cpp \ - $$PWD/dsimagecapturecontrol.cpp \ - $$PWD/dscamerasession.cpp \ - $$PWD/dscameraviewfindersettingscontrol.cpp \ - $$PWD/dscameraimageprocessingcontrol.cpp \ - $$PWD/directshowcameraexposurecontrol.cpp \ - $$PWD/directshowcameracapturedestinationcontrol.cpp \ - $$PWD/directshowcameracapturebufferformatcontrol.cpp \ - $$PWD/directshowcamerazoomcontrol.cpp \ - $$PWD/directshowcameraimageencodercontrol.cpp - -*-msvc*:INCLUDEPATH += $$(DXSDK_DIR)/include -QMAKE_USE += directshow diff --git a/src/plugins/directshow/camera/directshowcameracapturebufferformatcontrol.cpp b/src/plugins/directshow/camera/directshowcameracapturebufferformatcontrol.cpp deleted file mode 100644 index cc0a0ad17..000000000 --- a/src/plugins/directshow/camera/directshowcameracapturebufferformatcontrol.cpp +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowcameracapturebufferformatcontrol.h" - -#include "dscamerasession.h" - -QT_BEGIN_NAMESPACE - -DirectShowCameraCaptureBufferFormatControl::DirectShowCameraCaptureBufferFormatControl() -{ -} - -QList<QVideoFrame::PixelFormat> DirectShowCameraCaptureBufferFormatControl::supportedBufferFormats() const -{ - return QList<QVideoFrame::PixelFormat>() << QVideoFrame::Format_RGB32; -} - -QVideoFrame::PixelFormat DirectShowCameraCaptureBufferFormatControl::bufferFormat() const -{ - return QVideoFrame::Format_RGB32; -} - -void DirectShowCameraCaptureBufferFormatControl::setBufferFormat(QVideoFrame::PixelFormat format) -{ - Q_UNUSED(format); -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/camera/directshowcameracapturebufferformatcontrol.h b/src/plugins/directshow/camera/directshowcameracapturebufferformatcontrol.h deleted file mode 100644 index cacd3652b..000000000 --- a/src/plugins/directshow/camera/directshowcameracapturebufferformatcontrol.h +++ /dev/null @@ -1,60 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWCAMERACAPTUREBUFFERFORMATCONTROL_H -#define DIRECTSHOWCAMERACAPTUREBUFFERFORMATCONTROL_H - -#include <QtMultimedia/qcameracapturebufferformatcontrol.h> - -QT_BEGIN_NAMESPACE - -class DirectShowCameraCaptureBufferFormatControl : public QCameraCaptureBufferFormatControl -{ - Q_OBJECT -public: - DirectShowCameraCaptureBufferFormatControl(); - - QList<QVideoFrame::PixelFormat> supportedBufferFormats() const override; - QVideoFrame::PixelFormat bufferFormat() const override; - void setBufferFormat(QVideoFrame::PixelFormat format) override; -}; - -QT_END_NAMESPACE - -#endif // DIRECTSHOWCAMERACAPTUREBUFFERFORMATCONTROL_H diff --git a/src/plugins/directshow/camera/directshowcameracapturedestinationcontrol.cpp b/src/plugins/directshow/camera/directshowcameracapturedestinationcontrol.cpp deleted file mode 100644 index bfb10fc03..000000000 --- a/src/plugins/directshow/camera/directshowcameracapturedestinationcontrol.cpp +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowcameracapturedestinationcontrol.h" - -#include "dscamerasession.h" - -QT_BEGIN_NAMESPACE - -DirectShowCameraCaptureDestinationControl::DirectShowCameraCaptureDestinationControl(DSCameraSession *session) - : m_session(session) -{ - connect(m_session, &DSCameraSession::captureDestinationChanged, - this, &DirectShowCameraCaptureDestinationControl::captureDestinationChanged); -} - -bool DirectShowCameraCaptureDestinationControl::isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const -{ - return m_session->isCaptureDestinationSupported(destination); -} - -QCameraImageCapture::CaptureDestinations DirectShowCameraCaptureDestinationControl::captureDestination() const -{ - return m_session->captureDestination(); -} - -void DirectShowCameraCaptureDestinationControl::setCaptureDestination(QCameraImageCapture::CaptureDestinations destination) -{ - m_session->setCaptureDestination(destination); -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/camera/directshowcameracapturedestinationcontrol.h b/src/plugins/directshow/camera/directshowcameracapturedestinationcontrol.h deleted file mode 100644 index 224df9dbc..000000000 --- a/src/plugins/directshow/camera/directshowcameracapturedestinationcontrol.h +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWCAMERACAPTUREDESTINATIONCONTROL_H -#define DIRECTSHOWCAMERACAPTUREDESTINATIONCONTROL_H - -#include <QtMultimedia/qcameracapturedestinationcontrol.h> - -QT_BEGIN_NAMESPACE - -class DSCameraSession; - -class DirectShowCameraCaptureDestinationControl : public QCameraCaptureDestinationControl -{ - Q_OBJECT -public: - DirectShowCameraCaptureDestinationControl(DSCameraSession *session); - - bool isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const override; - QCameraImageCapture::CaptureDestinations captureDestination() const override; - void setCaptureDestination(QCameraImageCapture::CaptureDestinations destination) override; - -private: - DSCameraSession *m_session; - -}; - -QT_END_NAMESPACE - -#endif // DIRECTSHOWCAMERACAPTUREDESTINATIONCONTROL_H diff --git a/src/plugins/directshow/camera/directshowcameraexposurecontrol.cpp b/src/plugins/directshow/camera/directshowcameraexposurecontrol.cpp deleted file mode 100644 index 6f138450c..000000000 --- a/src/plugins/directshow/camera/directshowcameraexposurecontrol.cpp +++ /dev/null @@ -1,413 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowcameraexposurecontrol.h" -#include "dscamerasession.h" -#include "directshowglobal.h" -#include "directshowutils.h" - -#include <functional> -#include <cmath> - -QT_BEGIN_NAMESPACE - -static qreal convertToSec(long v) { return (v < 0) ? (1 / std::pow(2., qreal(v))) : std::pow(2., qreal(v)); } -static Q_DECL_CONSTEXPR qreal convertToFvalue(long v) { return qreal(v) / 10.; } - -DirectShowCameraExposureControl::DirectShowCameraExposureControl(DSCameraSession *session) - : m_session(session) - , m_shutterSpeedValues({ 0, 0, 0, 0, 0 }) - , m_apertureValues({ 0, 0, 0, 0, 0 }) - , m_requestedShutterSpeed(qreal(0.0)) - , m_currentShutterSpeed(qreal(-1.0)) - , m_requestedAperture(qreal(0.0)) - , m_currentAperture(qreal(-1.0)) - , m_requestedExposureMode(QCameraExposure::ExposureAuto) - , m_currentExposureMode(QCameraExposure::ExposureAuto) -{ - Q_ASSERT(m_session); - connect(m_session, &DSCameraSession::statusChanged, - this, &DirectShowCameraExposureControl::onStatusChanged); -} - -bool DirectShowCameraExposureControl::isParameterSupported(QCameraExposureControl::ExposureParameter parameter) const -{ - switch (parameter) { - case QCameraExposureControl::Aperture: - return (m_apertureValues.caps & CameraControl_Flags_Manual); - case QCameraExposureControl::ShutterSpeed: - return (m_shutterSpeedValues.caps & CameraControl_Flags_Manual); - case QCameraExposureControl::ExposureMode: - return true; - default: - break; - } - return false; -} - -QVariantList DirectShowCameraExposureControl::supportedParameterRange(QCameraExposureControl::ExposureParameter parameter, - bool *continuous) const -{ - if (continuous) - *continuous = false; - - if (parameter == ShutterSpeed) - return m_supportedShutterSpeeds; - - if (parameter == Aperture) - return m_supportedApertureValues; - - if (parameter == ExposureMode) - return m_supportedExposureModes; - - return QVariantList(); -} - -QVariant DirectShowCameraExposureControl::requestedValue(QCameraExposureControl::ExposureParameter parameter) const -{ - if (parameter == ShutterSpeed) - return QVariant::fromValue(m_requestedShutterSpeed); - - if (parameter == Aperture) - return QVariant::fromValue(m_requestedAperture); - - if (parameter == ExposureMode) - return QVariant::fromValue(m_requestedExposureMode); - - return QVariant(); -} - -QVariant DirectShowCameraExposureControl::actualValue(QCameraExposureControl::ExposureParameter parameter) const -{ - if (parameter == ExposureMode) - return QVariant::fromValue(m_currentExposureMode); - - if (parameter == ShutterSpeed) { - return qFuzzyCompare(m_currentShutterSpeed, qreal(-1.0)) - ? QVariant() - : QVariant::fromValue(m_currentShutterSpeed); - } - - if (parameter == Aperture) { - return qFuzzyCompare(m_currentAperture, qreal(-1.0)) - ? QVariant() - : QVariant::fromValue(m_currentAperture); - } - - return QVariant(); -} - -bool DirectShowCameraExposureControl::setValue(QCameraExposureControl::ExposureParameter parameter, - const QVariant &value) -{ - IAMCameraControl *cameraControl = nullptr; - const DirectShowUtils::ScopedSafeRelease<IAMCameraControl> rControl { &cameraControl }; - if (!m_session->getCameraControlInterface(&cameraControl)) - return false; - - // Reset exposure mode if the value is invalid. - if (!value.isValid()) { - m_requestedExposureMode = QCameraExposure::ExposureAuto; - return setExposureMode(cameraControl, m_requestedExposureMode); - } - - if (parameter == ShutterSpeed || parameter == Aperture) { - bool ok = false; - const qreal newValue = value.toReal(&ok); - if (!ok) - return false; - - // Change the exposure mode first - setExposureMode(cameraControl, QCameraExposure::ExposureManual); - - if (parameter == ShutterSpeed) { - m_requestedShutterSpeed = newValue; - return setShutterSpeed(cameraControl, m_requestedShutterSpeed); - } - m_requestedAperture = newValue; - return setAperture(cameraControl, m_requestedAperture); - } - - if (parameter == ExposureMode) { - m_requestedExposureMode = value.value<QCameraExposure::ExposureMode>(); - return setExposureMode(cameraControl, m_requestedExposureMode); - } - - return false; -} - -void DirectShowCameraExposureControl::onStatusChanged(QCamera::Status status) -{ - const bool shouldUpdate = (qFuzzyCompare(m_currentAperture, qreal(-1.0)) && qFuzzyCompare(m_currentShutterSpeed, qreal(-1.0))); - - if (status == QCamera::LoadedStatus && shouldUpdate) - updateExposureSettings(); - - if (status == QCamera::UnloadedStatus) { - m_supportedApertureValues.clear(); - m_supportedExposureModes.clear(); - m_supportedShutterSpeeds.clear(); - m_currentAperture = qreal(-1.0); - m_currentShutterSpeed = qreal(-1.0); - m_currentExposureMode = QCameraExposure::ExposureAuto; - } -} - -void DirectShowCameraExposureControl::updateExposureSettings() -{ - IAMCameraControl *cameraControl = nullptr; - const DirectShowUtils::ScopedSafeRelease<IAMCameraControl> rControl { &cameraControl }; - if (!m_session->getCameraControlInterface(&cameraControl)) - return; - - const auto updateValues = [cameraControl](long property, - ExposureValues ¤tValues, - QVariantList ¶meterRange, - const std::function<qreal(long)> &converter, - bool *changed) -> bool { - ExposureValues values { 0, 0, 0, 0, 0 }; - if (FAILED(cameraControl->GetRange(property, - &values.minValue, - &values.maxValue, - &values.stepping, - &values.defaultValue, - &values.caps))) { - return false; - } - - const bool minValueChanged = values.minValue != currentValues.minValue; - const bool maxValueChanged = values.maxValue != currentValues.maxValue; - const bool steppingChanged = values.stepping != currentValues.stepping; - - if (minValueChanged || maxValueChanged || steppingChanged) { - parameterRange.clear(); - long nextValue = values.minValue; - while (nextValue != values.maxValue && values.stepping != 0) { - parameterRange << converter(nextValue); - nextValue += values.stepping; - } - - if (changed) - *changed = true; - } - - currentValues = values; - return true; - }; - - const auto getCurrentValue = [cameraControl](long property, const std::function<qreal(long)> &converter, qreal *value) -> bool { - long currentValue; - long currentFlags; - if (FAILED(cameraControl->Get(property, ¤tValue, ¤tFlags))) - return false; - - *value = converter(currentValue); - return true; - }; - - // Shutter speed - bool changed = false; - if (!updateValues(CameraControl_Exposure, m_shutterSpeedValues, m_supportedShutterSpeeds, convertToSec, &changed)) - qCDebug(qtDirectShowPlugin, "Unable to update the shutter speed values"); - - if (changed) - Q_EMIT parameterRangeChanged(int(ShutterSpeed)); - - if ((m_shutterSpeedValues.caps & CameraControl_Flags_Manual)) { - if (getCurrentValue(CameraControl_Exposure, convertToSec, &m_currentShutterSpeed)) { - if (m_currentExposureMode == QCameraExposure::ExposureManual) - setShutterSpeed(cameraControl, m_requestedShutterSpeed); - } else { - m_currentShutterSpeed = qreal(-1.0); - qCDebug(qtDirectShowPlugin, "Unable to get the current shutter speed!"); - } - } - - // Aperture - changed = false; - if (!updateValues(CameraControl_Iris, m_apertureValues, m_supportedApertureValues, convertToFvalue, &changed)) - qCDebug(qtDirectShowPlugin, "Unable to update the aperture values"); - - if (changed) - Q_EMIT parameterRangeChanged(int(Aperture)); - - if (getCurrentValue(CameraControl_Iris, convertToFvalue, &m_currentAperture)) { - if (m_currentExposureMode == QCameraExposure::ExposureManual) - setAperture(cameraControl, m_requestedAperture); - } else { - m_currentAperture = qreal(-1.0); - qCDebug(qtDirectShowPlugin, "Unable to get the current aperture value!"); - } - - // Update exposure modes - const bool hasAutoExposure = (m_apertureValues.caps & CameraControl_Flags_Auto) - || (m_shutterSpeedValues.caps & CameraControl_Flags_Auto); - const bool hasManualExposure = (m_apertureValues.caps & CameraControl_Flags_Manual) - || (m_shutterSpeedValues.caps & CameraControl_Flags_Manual); - - QVariantList exposureModes; - if (hasAutoExposure && !m_supportedExposureModes.contains(QVariant::fromValue(QCameraExposure::ExposureAuto))) - exposureModes << QVariant::fromValue(QCameraExposure::ExposureAuto); - - if (hasManualExposure && !m_supportedExposureModes.contains(QVariant::fromValue(QCameraExposure::ExposureManual))) - exposureModes << QVariant::fromValue(QCameraExposure::ExposureManual); - - if (!exposureModes.isEmpty() || !m_supportedExposureModes.isEmpty()) { - m_supportedExposureModes = exposureModes; - Q_EMIT parameterRangeChanged(int(ExposureMode)); - } -} - -bool DirectShowCameraExposureControl::setShutterSpeed(IAMCameraControl *cameraControl, qreal shutterSpeed) -{ - if (m_currentExposureMode != QCameraExposure::ExposureManual) { - qCDebug(qtDirectShowPlugin, "Trying to set shutter speed value while in auto exposure mode!"); - return false; - } - - if (qFuzzyCompare(m_currentShutterSpeed, shutterSpeed)) - return true; - - if ((m_shutterSpeedValues.caps & CameraControl_Flags_Manual) == 0) - return false; - - if (!m_supportedShutterSpeeds.contains(QVariant::fromValue(shutterSpeed))) - return false; - - if (qFuzzyIsNull(shutterSpeed) || (shutterSpeed < qreal(0.0))) - return false; - - const long newValue = long(log2(shutterSpeed)); - if (FAILED(cameraControl->Set(CameraControl_Exposure, newValue, CameraControl_Flags_Manual))) { - qCDebug(qtDirectShowPlugin, "Unable to set shutter speed value to: %d", int(shutterSpeed)); - return false; - } - - m_currentShutterSpeed = shutterSpeed; - Q_EMIT actualValueChanged(int(ShutterSpeed)); - return true; -} - -bool DirectShowCameraExposureControl::setAperture(IAMCameraControl *cameraControl, qreal aperture) -{ - if (m_currentExposureMode != QCameraExposure::ExposureManual) { - qCDebug(qtDirectShowPlugin, "Trying to set aperture value while in auto exposure mode!"); - return false; - } - - if (qFuzzyCompare(m_currentAperture, aperture)) - return true; - - if ((m_apertureValues.caps & CameraControl_Flags_Manual) == 0) - return false; - - if (!m_supportedApertureValues.contains(QVariant::fromValue(aperture))) - return false; - - if (aperture < qreal(0.0)) - return false; - - const long newValue = long(10 * aperture); - if (FAILED(cameraControl->Set(CameraControl_Iris, newValue, CameraControl_Flags_Manual))) { - qCDebug(qtDirectShowPlugin, "Unable to set aperture value to: %d", int(aperture)); - return false; - } - - m_currentAperture = aperture; - Q_EMIT actualValueChanged(int(Aperture)); - - return true; -} - -bool DirectShowCameraExposureControl::setExposureMode(IAMCameraControl *cameraControl, QCameraExposure::ExposureMode mode) -{ - if (m_currentExposureMode == mode) - return true; - - bool exposureModeChanged = true; - - // Set auto exposure mode - if (mode == QCameraExposure::ExposureAuto) { - if ((m_apertureValues.caps & CameraControl_Flags_Auto) - && FAILED(cameraControl->Set(CameraControl_Iris, 0, CameraControl_Flags_Auto))) { - qCDebug(qtDirectShowPlugin, "Setting auto exposure mode failed!"); - exposureModeChanged = false; - } - - if ((m_shutterSpeedValues.caps & CameraControl_Flags_Auto) - && FAILED(cameraControl->Set(CameraControl_Exposure, 0, CameraControl_Flags_Auto))) { - qCDebug(qtDirectShowPlugin, "Setting auto exposure mode failed"); - exposureModeChanged = false; - } - - if (exposureModeChanged) { - m_currentExposureMode = mode; - Q_EMIT actualValueChanged(int(ExposureMode)); - } - - return exposureModeChanged; - } - - // Change the current exposure mode to manual first. - m_currentExposureMode = QCameraExposure::ExposureManual; - - const qreal newShutterSpeed = qFuzzyCompare(m_requestedShutterSpeed, -1.0) - ? convertToSec(m_shutterSpeedValues.defaultValue) - : m_requestedShutterSpeed; - if ((m_shutterSpeedValues.caps & CameraControl_Flags_Manual)) - setShutterSpeed(cameraControl, newShutterSpeed); - - const qreal newAperture = qFuzzyCompare(m_requestedAperture, -1.0) - ? convertToFvalue(m_apertureValues.defaultValue) - : m_requestedAperture; - if ((m_apertureValues.caps & CameraControl_Flags_Manual)) - setAperture(cameraControl, newAperture); - - - // Check if any of the values changed. - exposureModeChanged = (qFuzzyCompare(m_currentShutterSpeed, newShutterSpeed) - || qFuzzyCompare(m_currentAperture, newAperture)); - - if (exposureModeChanged) - Q_EMIT actualValueChanged(int(ExposureMode)); - - return exposureModeChanged; -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/camera/directshowcameraexposurecontrol.h b/src/plugins/directshow/camera/directshowcameraexposurecontrol.h deleted file mode 100644 index db3fc5984..000000000 --- a/src/plugins/directshow/camera/directshowcameraexposurecontrol.h +++ /dev/null @@ -1,100 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWCAMERAEXPOSURECONTROL_H -#define DIRECTSHOWCAMERAEXPOSURECONTROL_H - -#include <QtMultimedia/qcameraexposurecontrol.h> - -struct IAMCameraControl; - -QT_BEGIN_NAMESPACE - -class DSCameraSession; - -class DirectShowCameraExposureControl : public QCameraExposureControl -{ - Q_OBJECT -public: - DirectShowCameraExposureControl(DSCameraSession *session); - - bool isParameterSupported(ExposureParameter parameter) const override; - QVariantList supportedParameterRange(ExposureParameter parameter, bool *continuous) const override; - QVariant requestedValue(ExposureParameter parameter) const override; - QVariant actualValue(ExposureParameter parameter) const override; - bool setValue(ExposureParameter parameter, const QVariant &value) override; - -private Q_SLOTS: - void onStatusChanged(QCamera::Status status); - -private: - DSCameraSession *m_session; - - struct ExposureValues - { - long caps; - long minValue; - long maxValue; - long stepping; - long defaultValue; - } m_shutterSpeedValues, m_apertureValues; - - qreal m_requestedShutterSpeed; - qreal m_currentShutterSpeed; - - qreal m_requestedAperture; - qreal m_currentAperture; - - QVariantList m_supportedShutterSpeeds; - QVariantList m_supportedApertureValues; - QVariantList m_supportedExposureModes; - - QCameraExposure::ExposureMode m_requestedExposureMode; - QCameraExposure::ExposureMode m_currentExposureMode; - - void updateExposureSettings(); - - bool setShutterSpeed(IAMCameraControl *cameraControl, qreal shutterSpeed); - bool setAperture(IAMCameraControl *cameraControl, qreal aperture); - bool setExposureMode(IAMCameraControl *cameraControl, QCameraExposure::ExposureMode mode); -}; - -QT_END_NAMESPACE - -#endif // DIRECTSHOWCAMERAEXPOSURECONTROL_H diff --git a/src/plugins/directshow/camera/directshowcameraglobal.h b/src/plugins/directshow/camera/directshowcameraglobal.h deleted file mode 100644 index 917ae2dc7..000000000 --- a/src/plugins/directshow/camera/directshowcameraglobal.h +++ /dev/null @@ -1,231 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWCAMERAGLOBAL_H -#define DIRECTSHOWCAMERAGLOBAL_H - -#include <QtCore/qglobal.h> - -#include <dshow.h> - -extern const GUID MEDIASUBTYPE_RGB24; -extern const GUID MEDIASUBTYPE_RGB32; -extern const GUID MEDIASUBTYPE_YUY2; -extern const GUID MEDIASUBTYPE_MJPG; -extern const GUID MEDIASUBTYPE_RGB555; -extern const GUID MEDIASUBTYPE_YVU9; -extern const GUID MEDIASUBTYPE_UYVY; -extern const GUID PIN_CATEGORY_CAPTURE; -extern const GUID PIN_CATEGORY_PREVIEW; - -extern const IID IID_IPropertyBag; -extern const IID IID_ISampleGrabber; -extern const IID IID_ICaptureGraphBuilder2; -extern const IID IID_IAMStreamConfig; - - -extern const CLSID CLSID_CVidCapClassManager; -extern const CLSID CLSID_VideoInputDeviceCategory; -extern const CLSID CLSID_SampleGrabber; -extern const CLSID CLSID_CaptureGraphBuilder2; - -#define SAFE_RELEASE(x) { if (x) x->Release(); x = nullptr; } - -typedef struct IFileSinkFilter *LPFILESINKFILTER; -typedef struct IAMCopyCaptureFileProgress *LPAMCOPYCAPTUREFILEPROGRESS; - -#ifndef __ICaptureGraphBuilder2_INTERFACE_DEFINED__ -#define __ICaptureGraphBuilder2_INTERFACE_DEFINED__ -struct ICaptureGraphBuilder2 : public IUnknown -{ -public: - virtual HRESULT STDMETHODCALLTYPE SetFiltergraph( - /* [in] */ IGraphBuilder *pfg) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFiltergraph( - /* [out] */ IGraphBuilder **ppfg) = 0; - - virtual HRESULT STDMETHODCALLTYPE SetOutputFileName( - /* [in] */ const GUID *pType, - /* [in] */ LPCOLESTR lpstrFile, - /* [out] */ IBaseFilter **ppf, - /* [out] */ IFileSinkFilter **ppSink) = 0; - - virtual /* [local] */ HRESULT STDMETHODCALLTYPE FindInterface( - /* [in] */ const GUID *pCategory, - /* [in] */ const GUID *pType, - /* [in] */ IBaseFilter *pf, - /* [in] */ REFIID riid, - /* [out] */ void **ppint) = 0; - - virtual HRESULT STDMETHODCALLTYPE RenderStream( - /* [in] */ const GUID *pCategory, - /* [in] */ const GUID *pType, - /* [in] */ IUnknown *pSource, - /* [in] */ IBaseFilter *pfCompressor, - /* [in] */ IBaseFilter *pfRenderer) = 0; - - virtual HRESULT STDMETHODCALLTYPE ControlStream( - /* [in] */ const GUID *pCategory, - /* [in] */ const GUID *pType, - /* [in] */ IBaseFilter *pFilter, - /* [in] */ REFERENCE_TIME *pstart, - /* [in] */ REFERENCE_TIME *pstop, - /* [in] */ WORD wStartCookie, - /* [in] */ WORD wStopCookie) = 0; - - virtual HRESULT STDMETHODCALLTYPE AllocCapFile( - /* [in] */ LPCOLESTR lpstr, - /* [in] */ DWORDLONG dwlSize) = 0; - - virtual HRESULT STDMETHODCALLTYPE CopyCaptureFile( - /* [in] */ LPOLESTR lpwstrOld, - /* [in] */ LPOLESTR lpwstrNew, - /* [in] */ int fAllowEscAbort, - /* [in] */ IAMCopyCaptureFileProgress *pCallback) = 0; - - virtual HRESULT STDMETHODCALLTYPE FindPin( - /* [in] */ IUnknown *pSource, - /* [in] */ PIN_DIRECTION pindir, - /* [in] */ const GUID *pCategory, - /* [in] */ const GUID *pType, - /* [in] */ BOOL fUnconnected, - /* [in] */ int num, - /* [out] */ IPin **ppPin) = 0; - -}; -#endif - -#ifndef __IAMStreamConfig_INTERFACE_DEFINED__ -#define __IAMStreamConfig_INTERFACE_DEFINED__ -struct IAMStreamConfig : public IUnknown -{ -public: - virtual HRESULT STDMETHODCALLTYPE SetFormat( - /* [in] */ AM_MEDIA_TYPE *pmt) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetFormat( - /* [out] */ AM_MEDIA_TYPE **ppmt) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetNumberOfCapabilities( - /* [out] */ int *piCount, - /* [out] */ int *piSize) = 0; - - virtual HRESULT STDMETHODCALLTYPE GetStreamCaps( - /* [in] */ int iIndex, - /* [out] */ AM_MEDIA_TYPE **ppmt, - /* [out] */ BYTE *pSCC) = 0; - -}; -#endif - -#ifndef __IErrorLog_INTERFACE_DEFINED__ -#define __IErrorLog_INTERFACE_DEFINED__ -struct IErrorLog : public IUnknown - { - public: - virtual HRESULT STDMETHODCALLTYPE AddError( - /* [in] */ LPCOLESTR pszPropName, - /* [in] */ EXCEPINFO *pExcepInfo) = 0; - - }; -#endif - -#ifndef __IPropertyBag_INTERFACE_DEFINED__ -#define __IPropertyBag_INTERFACE_DEFINED__ -struct IPropertyBag : public IUnknown -{ -public: - virtual /* [local] */ HRESULT STDMETHODCALLTYPE Read( - /* [in] */ LPCOLESTR pszPropName, - /* [out][in] */ VARIANT *pVar, - /* [in] */ IErrorLog *pErrorLog) = 0; - - virtual HRESULT STDMETHODCALLTYPE Write( - /* [in] */ LPCOLESTR pszPropName, - /* [in] */ VARIANT *pVar) = 0; - -}; -#endif - -typedef struct IMediaSample *LPMEDIASAMPLE; - -EXTERN_C const IID IID_ISampleGrabberCB; - -#ifndef __ISampleGrabberCB_INTERFACE_DEFINED__ -#define __ISampleGrabberCB_INTERFACE_DEFINED__ - -#undef INTERFACE -#define INTERFACE ISampleGrabberCB -DECLARE_INTERFACE_(ISampleGrabberCB, IUnknown) -{ -// STDMETHOD(QueryInterface) (THIS_ const GUID *, void **) PURE; - STDMETHOD(QueryInterface) (THIS_ REFIID riid, void **) PURE; - STDMETHOD_(ULONG, AddRef) (THIS) PURE; - STDMETHOD_(ULONG, Release) (THIS) PURE; - STDMETHOD_(HRESULT, SampleCB) (THIS_ double, LPMEDIASAMPLE) PURE; - STDMETHOD_(HRESULT, BufferCB) (THIS_ double, BYTE *, long) PURE; -}; -#undef INTERFACE - -#endif - - -#ifndef __ISampleGrabber_INTERFACE_DEFINED__ -#define __ISampleGrabber_INTERFACE_DEFINED__ - -#define INTERFACE ISampleGrabber -DECLARE_INTERFACE_(ISampleGrabber,IUnknown) -{ - STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - STDMETHOD(SetOneShot)(THIS_ BOOL) PURE; - STDMETHOD(SetMediaType)(THIS_ const AM_MEDIA_TYPE*) PURE; - STDMETHOD(GetConnectedMediaType)(THIS_ AM_MEDIA_TYPE*) PURE; - STDMETHOD(SetBufferSamples)(THIS_ BOOL) PURE; - STDMETHOD(GetCurrentBuffer)(THIS_ long*,long*) PURE; - STDMETHOD(GetCurrentSample)(THIS_ IMediaSample**) PURE; - STDMETHOD(SetCallback)(THIS_ ISampleGrabberCB *,long) PURE; -}; -#undef INTERFACE -#endif - - -#endif diff --git a/src/plugins/directshow/camera/directshowcameraimageencodercontrol.cpp b/src/plugins/directshow/camera/directshowcameraimageencodercontrol.cpp deleted file mode 100644 index 912f67a2d..000000000 --- a/src/plugins/directshow/camera/directshowcameraimageencodercontrol.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowcameraimageencodercontrol.h" -#include "dscamerasession.h" -#include <QImageWriter> - -QT_BEGIN_NAMESPACE - -DirectShowCameraImageEncoderControl::DirectShowCameraImageEncoderControl(DSCameraSession *session) - : QImageEncoderControl(session) - , m_session(session) -{ -} - -QList<QSize> DirectShowCameraImageEncoderControl::supportedResolutions(const QImageEncoderSettings &settings, bool *continuous) const -{ - QList<QSize> res; - if (!settings.codec().isEmpty() && !supportedImageCodecs().contains(settings.codec(), Qt::CaseInsensitive)) - return res; - - QList<QSize> resolutions = m_session->supportedResolutions(continuous); - QSize r = settings.resolution(); - if (!r.isValid()) - return resolutions; - - if (resolutions.contains(r)) - res << settings.resolution(); - - return res; -} - -QStringList DirectShowCameraImageEncoderControl::supportedImageCodecs() const -{ - QStringList supportedCodecs; - for (const QByteArray &type: QImageWriter::supportedImageFormats()) { - supportedCodecs << type; - } - - return supportedCodecs; -} - -QString DirectShowCameraImageEncoderControl::imageCodecDescription(const QString &codecName) const -{ - Q_UNUSED(codecName); - return QString(); -} - -QImageEncoderSettings DirectShowCameraImageEncoderControl::imageSettings() const -{ - return m_session->imageEncoderSettings(); -} - -void DirectShowCameraImageEncoderControl::setImageSettings(const QImageEncoderSettings &settings) -{ - m_session->setImageEncoderSettings(settings); -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/camera/directshowcameraimageencodercontrol.h b/src/plugins/directshow/camera/directshowcameraimageencodercontrol.h deleted file mode 100644 index 6891bea77..000000000 --- a/src/plugins/directshow/camera/directshowcameraimageencodercontrol.h +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWCAMERAIMAGEENCODERCONTROL_H -#define DIRECTSHOWCAMERAIMAGEENCODERCONTROL_H - -#include <qimageencodercontrol.h> - -QT_BEGIN_NAMESPACE - -class DSCameraSession; -class DirectShowCameraImageEncoderControl : public QImageEncoderControl -{ - Q_OBJECT -public: - DirectShowCameraImageEncoderControl(DSCameraSession *session); - - QList<QSize> supportedResolutions( - const QImageEncoderSettings &settings = QImageEncoderSettings(), - bool *continuous = nullptr) const override; - - QStringList supportedImageCodecs() const override; - QString imageCodecDescription(const QString &formatName) const override; - - QImageEncoderSettings imageSettings() const override; - void setImageSettings(const QImageEncoderSettings &settings) override; - -private: - DSCameraSession *m_session; -}; - -QT_END_NAMESPACE - -#endif // DIRECTSHOWCAMERAIMAGEENCODERCONTROL_H diff --git a/src/plugins/directshow/camera/directshowcamerazoomcontrol.cpp b/src/plugins/directshow/camera/directshowcamerazoomcontrol.cpp deleted file mode 100644 index 079976e15..000000000 --- a/src/plugins/directshow/camera/directshowcamerazoomcontrol.cpp +++ /dev/null @@ -1,209 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowcamerazoomcontrol.h" -#include "dscamerasession.h" -#include "directshowutils.h" - -QT_BEGIN_NAMESPACE - -inline static qreal defaultZoomValue() { return qreal(1.0); } - -DirectShowCameraZoomControl::DirectShowCameraZoomControl(DSCameraSession *session) - : m_session(session) - , m_opticalZoom({0, 0, 0, 0, 0}) - , m_currentOpticalZoom(qreal(0.0)) - , m_requestedOpticalZoom(qreal(0.0)) - , m_maxOpticalZoom(qreal(1.0)) -{ - Q_ASSERT(m_session); - connect(m_session, &DSCameraSession::statusChanged, - this, &DirectShowCameraZoomControl::onStatusChanged); -} - -qreal DirectShowCameraZoomControl::maximumOpticalZoom() const -{ - return m_maxOpticalZoom; -} - -qreal DirectShowCameraZoomControl::maximumDigitalZoom() const -{ - return defaultZoomValue(); -} - -qreal DirectShowCameraZoomControl::requestedOpticalZoom() const -{ - return qMax(defaultZoomValue(), m_requestedOpticalZoom); -} - -qreal DirectShowCameraZoomControl::requestedDigitalZoom() const -{ - return defaultZoomValue(); -} - -qreal DirectShowCameraZoomControl::currentOpticalZoom() const -{ - return qMax(defaultZoomValue(), m_currentOpticalZoom); -} - -qreal DirectShowCameraZoomControl::currentDigitalZoom() const -{ - return defaultZoomValue(); -} - -void DirectShowCameraZoomControl::zoomTo(qreal optical, qreal digital) -{ - Q_UNUSED(digital); - if (!(m_opticalZoom.caps & CameraControl_Flags_Manual)) - return; - - if (qFuzzyCompare(optical, m_requestedOpticalZoom)) - return; - - m_requestedOpticalZoom = optical; - Q_EMIT requestedOpticalZoomChanged(m_requestedOpticalZoom); - - if (qFuzzyCompare(m_requestedOpticalZoom, m_currentOpticalZoom)) - return; - - if (m_session->status() != QCamera::LoadedStatus && m_session->status() != QCamera::ActiveStatus) - return; // We'll wait until the camera is loaded, see: statusChanged connection - - opticalZoomToPrivate(optical); -} - -void DirectShowCameraZoomControl::onStatusChanged(QCamera::Status status) -{ - if (status == QCamera::LoadedStatus) { - updateZoomValues(); - } else if (status == QCamera::UnloadedStatus) { - SecureZeroMemory(&m_opticalZoom, sizeof(ZoomValues)); - m_currentOpticalZoom = qreal(0.0); - m_requestedOpticalZoom = qreal(0.0); - } - -} - -void DirectShowCameraZoomControl::updateZoomValues() -{ - IAMCameraControl *cameraControl = nullptr; - const DirectShowUtils::ScopedSafeRelease<IAMCameraControl> rControl { &cameraControl }; - if (!m_session->getCameraControlInterface(&cameraControl)) - return; - - ZoomValues values { 0, 0, 0, 0, 0 }; - // Zoom levels in DS are in the range [10, 600] - // The default zoom is device specific. - HRESULT hr = cameraControl->GetRange(CameraControl_Zoom, - &values.minZoom, - &values.maxZoom, - &values.stepping, - &values.defaultZoom, - &values.caps); - - if (FAILED(hr)) { - qCDebug(qtDirectShowPlugin, "Getting the camera's zoom properties failed"); - SecureZeroMemory(&m_opticalZoom, sizeof(ZoomValues)); - return; - } - - if (!(values.caps & CameraControl_Flags_Manual)) { - qCDebug(qtDirectShowPlugin, "Camera does not support manual zoom"); - SecureZeroMemory(&m_opticalZoom, sizeof(ZoomValues)); - return; - } - - if (values.maxZoom != m_opticalZoom.maxZoom) { - const qreal newMaxZoomScale = (values.minZoom == 0) ? defaultZoomValue() - : (qreal(values.maxZoom) / qreal(values.minZoom)); - if (!qFuzzyCompare(newMaxZoomScale, m_maxOpticalZoom)) { - m_maxOpticalZoom = newMaxZoomScale; - Q_EMIT maximumOpticalZoomChanged(m_maxOpticalZoom); - } - } - - m_opticalZoom = values; - - long currentZoom = 0; - long flags = 0; - if (FAILED(cameraControl->Get(CameraControl_Zoom, ¤tZoom, &flags))) { - qCDebug(qtDirectShowPlugin, "Getting the camera's current zoom value failed!"); - return; - } - - qreal currentOpticalZoom = (m_opticalZoom.minZoom == 0) ? defaultZoomValue() - : (qreal(currentZoom) / qreal(m_opticalZoom.minZoom)); - currentOpticalZoom = qMax(defaultZoomValue(), currentOpticalZoom); - if (!qFuzzyCompare(m_currentOpticalZoom, currentOpticalZoom)) { - m_currentOpticalZoom = currentOpticalZoom; - Q_EMIT currentOpticalZoomChanged(m_currentOpticalZoom); - } - - // Check if there is a pending zoom value. - if (!qFuzzyCompare(m_currentOpticalZoom, m_requestedOpticalZoom) && !qFuzzyIsNull(m_requestedOpticalZoom)) - opticalZoomToPrivate(m_requestedOpticalZoom); -} - -bool DirectShowCameraZoomControl::opticalZoomToPrivate(qreal scaleFactor) -{ - IAMCameraControl *cameraControl = nullptr; - const DirectShowUtils::ScopedSafeRelease<IAMCameraControl> rControl { &cameraControl }; - if (!m_session->getCameraControlInterface(&cameraControl)) - return false; - - // Convert to DS zoom value - const int newDSOpticalZoom = qRound(m_opticalZoom.minZoom * scaleFactor); - long newDSOpticalZoomAdjusted = newDSOpticalZoom - (newDSOpticalZoom % m_opticalZoom.stepping); - newDSOpticalZoomAdjusted = qBound(m_opticalZoom.minZoom, newDSOpticalZoomAdjusted, m_opticalZoom.maxZoom); - - if (FAILED(cameraControl->Set(CameraControl_Zoom, newDSOpticalZoomAdjusted, CameraControl_Flags_Manual))) { - qCDebug(qtDirectShowPlugin, "Setting the camera's zoom value failed"); - return false; - } - - const qreal newScaleFactor = (m_opticalZoom.minZoom == 0) ? defaultZoomValue() - : (qreal(newDSOpticalZoomAdjusted) / qreal(m_opticalZoom.minZoom)); - // convert back to Qt scale value - m_currentOpticalZoom = qMax(defaultZoomValue(), newScaleFactor); - Q_EMIT currentOpticalZoomChanged(m_currentOpticalZoom); - - return true; -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/camera/directshowcamerazoomcontrol.h b/src/plugins/directshow/camera/directshowcamerazoomcontrol.h deleted file mode 100644 index f6fb05b0e..000000000 --- a/src/plugins/directshow/camera/directshowcamerazoomcontrol.h +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2018 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWCAMERAZOOMCONTROL_H -#define DIRECTSHOWCAMERAZOOMCONTROL_H - -#include <QtMultimedia/qcamerazoomcontrol.h> -#include <QtMultimedia/qcamera.h> - -QT_BEGIN_NAMESPACE - -class DSCameraSession; - -class DirectShowCameraZoomControl : public QCameraZoomControl -{ - Q_OBJECT -public: - DirectShowCameraZoomControl(DSCameraSession *session); - - qreal maximumOpticalZoom() const override; - qreal maximumDigitalZoom() const override; - qreal requestedOpticalZoom() const override; - qreal requestedDigitalZoom() const override; - qreal currentOpticalZoom() const override; - qreal currentDigitalZoom() const override; - void zoomTo(qreal optical, qreal digital) override; - -private Q_SLOTS: - void onStatusChanged(QCamera::Status status); - -private: - DSCameraSession *m_session; - struct ZoomValues - { - long maxZoom; - long minZoom; - long stepping; - long defaultZoom; - long caps; - } m_opticalZoom; - - qreal m_currentOpticalZoom; - qreal m_requestedOpticalZoom; - qreal m_maxOpticalZoom; - - void updateZoomValues(); - bool opticalZoomToPrivate(qreal value); -}; - -QT_END_NAMESPACE - -#endif // DIRECTSHOWCAMERAZOOMCONTROL_H diff --git a/src/plugins/directshow/camera/dscameracontrol.cpp b/src/plugins/directshow/camera/dscameracontrol.cpp deleted file mode 100644 index 3f60ec848..000000000 --- a/src/plugins/directshow/camera/dscameracontrol.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtCore/qdebug.h> - -#include "dscameracontrol.h" -#include "dscameraservice.h" -#include "dscamerasession.h" - -QT_BEGIN_NAMESPACE - -DSCameraControl::DSCameraControl(QObject *parent) - : QCameraControl(parent) -{ - m_session = qobject_cast<DSCameraSession*>(parent); - connect(m_session, &DSCameraSession::statusChanged, this, - [&](QCamera::Status status) { - if (status == QCamera::UnloadedStatus) - m_state = QCamera::UnloadedState; - emit statusChanged(status); - }); - connect(m_session, &DSCameraSession::cameraError, - this, &DSCameraControl::error); -} - -DSCameraControl::~DSCameraControl() = default; - -void DSCameraControl::setState(QCamera::State state) -{ - if (m_state == state) - return; - - bool succeeded = false; - switch (state) { - case QCamera::UnloadedState: - succeeded = m_session->unload(); - break; - case QCamera::LoadedState: - case QCamera::ActiveState: - if (m_state == QCamera::UnloadedState && !m_session->load()) - return; - - if (state == QCamera::ActiveState) - succeeded = m_session->startPreview(); - else - succeeded = m_session->stopPreview(); - - break; - } - - if (succeeded) { - m_state = state; - emit stateChanged(m_state); - } -} - -bool DSCameraControl::isCaptureModeSupported(QCamera::CaptureModes mode) const -{ - bool bCaptureSupported = false; - switch (mode) { - case QCamera::CaptureStillImage: - bCaptureSupported = true; - break; - case QCamera::CaptureVideo: - bCaptureSupported = false; - break; - } - return bCaptureSupported; -} - -void DSCameraControl::setCaptureMode(QCamera::CaptureModes mode) -{ - if (m_captureMode != mode && isCaptureModeSupported(mode)) { - m_captureMode = mode; - emit captureModeChanged(mode); - } -} - -QCamera::Status DSCameraControl::status() const -{ - return m_session->status(); -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/camera/dscameracontrol.h b/src/plugins/directshow/camera/dscameracontrol.h deleted file mode 100644 index 2087623d1..000000000 --- a/src/plugins/directshow/camera/dscameracontrol.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DSCAMERACONTROL_H -#define DSCAMERACONTROL_H - -#include <QtCore/qobject.h> -#include <qcameracontrol.h> - -QT_BEGIN_NAMESPACE - -class DSCameraSession; - - -class DSCameraControl : public QCameraControl -{ - Q_OBJECT -public: - DSCameraControl(QObject *parent = nullptr); - ~DSCameraControl() override; - - QCamera::State state() const override { return m_state; } - - QCamera::CaptureModes captureMode() const override { return m_captureMode; } - void setCaptureMode(QCamera::CaptureModes mode) override; - - void setState(QCamera::State state) override; - - QCamera::Status status() const override; - bool isCaptureModeSupported(QCamera::CaptureModes mode) const override; - bool canChangeProperty(PropertyChangeType, QCamera::Status) const override - { return false; } - -private: - DSCameraSession *m_session; - QCamera::State m_state = QCamera::UnloadedState; - QCamera::CaptureModes m_captureMode = QCamera::CaptureStillImage; -}; - -QT_END_NAMESPACE - -#endif - - diff --git a/src/plugins/directshow/camera/dscameraimageprocessingcontrol.cpp b/src/plugins/directshow/camera/dscameraimageprocessingcontrol.cpp deleted file mode 100644 index 6d0f45ae9..000000000 --- a/src/plugins/directshow/camera/dscameraimageprocessingcontrol.cpp +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Denis Shienkov <denis.shienkov@gmail.com> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "dscameraimageprocessingcontrol.h" -#include "dscamerasession.h" - -QT_BEGIN_NAMESPACE - -DSCameraImageProcessingControl::DSCameraImageProcessingControl(DSCameraSession *session) - : QCameraImageProcessingControl(session) - , m_session(session) -{ -} - -DSCameraImageProcessingControl::~DSCameraImageProcessingControl() = default; - -bool DSCameraImageProcessingControl::isParameterSupported( - QCameraImageProcessingControl::ProcessingParameter parameter) const -{ - return m_session->isImageProcessingParameterSupported(parameter); -} - -bool DSCameraImageProcessingControl::isParameterValueSupported( - QCameraImageProcessingControl::ProcessingParameter parameter, - const QVariant &value) const -{ - return m_session->isImageProcessingParameterValueSupported(parameter, value); -} - -QVariant DSCameraImageProcessingControl::parameter( - QCameraImageProcessingControl::ProcessingParameter parameter) const -{ - return m_session->imageProcessingParameter(parameter); -} - -void DSCameraImageProcessingControl::setParameter(QCameraImageProcessingControl::ProcessingParameter parameter, - const QVariant &value) -{ - m_session->setImageProcessingParameter(parameter, value); -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/camera/dscameraimageprocessingcontrol.h b/src/plugins/directshow/camera/dscameraimageprocessingcontrol.h deleted file mode 100644 index 48f1b6b2c..000000000 --- a/src/plugins/directshow/camera/dscameraimageprocessingcontrol.h +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 Denis Shienkov <denis.shienkov@gmail.com> -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DSCAMERAIMAGEPROCESSINGCONTROL_H -#define DSCAMERAIMAGEPROCESSINGCONTROL_H - -#include <qcamera.h> -#include <qcameraimageprocessingcontrol.h> - -QT_BEGIN_NAMESPACE - -class DSCameraSession; - -class DSCameraImageProcessingControl : public QCameraImageProcessingControl -{ - Q_OBJECT - -public: - DSCameraImageProcessingControl(DSCameraSession *session); - ~DSCameraImageProcessingControl() override; - - bool isParameterSupported(ProcessingParameter) const override; - bool isParameterValueSupported(ProcessingParameter parameter, - const QVariant &value) const override; - QVariant parameter(ProcessingParameter parameter) const override; - void setParameter(ProcessingParameter parameter, const QVariant &value) override; - -private: - DSCameraSession *m_session; -}; - -QT_END_NAMESPACE - -#endif // DSCAMERAIMAGEPROCESSINGCONTROL_H diff --git a/src/plugins/directshow/camera/dscameraservice.cpp b/src/plugins/directshow/camera/dscameraservice.cpp deleted file mode 100644 index ff488cf09..000000000 --- a/src/plugins/directshow/camera/dscameraservice.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtCore/qvariant.h> -#include <QtCore/qdebug.h> - -#include "dscameraservice.h" -#include "dscameracontrol.h" -#include "dscamerasession.h" -#include "dsvideorenderer.h" -#include "dsvideodevicecontrol.h" -#include "dsimagecapturecontrol.h" -#include "dscameraviewfindersettingscontrol.h" -#include "dscameraimageprocessingcontrol.h" -#include "directshowcameraexposurecontrol.h" -#include "directshowcameracapturedestinationcontrol.h" -#include "directshowcameracapturebufferformatcontrol.h" -#include "directshowvideoprobecontrol.h" -#include "directshowcamerazoomcontrol.h" -#include "directshowcameraimageencodercontrol.h" - -QT_BEGIN_NAMESPACE - -DSCameraService::DSCameraService(QObject *parent): - QMediaService(parent) - , m_session(new DSCameraSession(this)) - , m_control(new DSCameraControl(m_session)) - , m_videoDevice(new DSVideoDeviceControl(m_session)) - , m_imageCapture(new DSImageCaptureControl(m_session)) - , m_viewfinderSettings(new DSCameraViewfinderSettingsControl(m_session)) - , m_imageProcessingControl(new DSCameraImageProcessingControl(m_session)) - , m_exposureControl(new DirectShowCameraExposureControl(m_session)) - , m_captureDestinationControl(new DirectShowCameraCaptureDestinationControl(m_session)) - , m_captureBufferFormatControl(new DirectShowCameraCaptureBufferFormatControl) - , m_zoomControl(new DirectShowCameraZoomControl(m_session)) - , m_imageEncoderControl(new DirectShowCameraImageEncoderControl(m_session)) -{ -} - -DSCameraService::~DSCameraService() -{ - delete m_control; - delete m_viewfinderSettings; - delete m_imageProcessingControl; - delete m_videoDevice; - delete m_videoRenderer; - delete m_imageCapture; - delete m_imageEncoderControl; - delete m_session; - delete m_exposureControl; - delete m_captureDestinationControl; - delete m_captureBufferFormatControl; - delete m_videoProbeControl; - delete m_zoomControl; -} - -QMediaControl* DSCameraService::requestControl(const char *name) -{ - if(qstrcmp(name,QCameraControl_iid) == 0) - return m_control; - - if (qstrcmp(name, QCameraImageCaptureControl_iid) == 0) - return m_imageCapture; - - if (qstrcmp(name,QVideoRendererControl_iid) == 0) { - if (!m_videoRenderer) { - m_videoRenderer = new DSVideoRendererControl(m_session, this); - return m_videoRenderer; - } - } - - if (qstrcmp(name,QVideoDeviceSelectorControl_iid) == 0) - return m_videoDevice; - - if (qstrcmp(name, QCameraViewfinderSettingsControl2_iid) == 0) - return m_viewfinderSettings; - - if (qstrcmp(name, QCameraImageProcessingControl_iid) == 0) - return m_imageProcessingControl; - - if (qstrcmp(name, QCameraExposureControl_iid) == 0) - return m_exposureControl; - - if (qstrcmp(name, QCameraCaptureDestinationControl_iid) == 0) - return m_captureDestinationControl; - - if (qstrcmp(name, QCameraCaptureBufferFormatControl_iid) == 0) - return m_captureBufferFormatControl; - - if (qstrcmp(name, QMediaVideoProbeControl_iid) == 0) { - if (!m_videoProbeControl) - m_videoProbeControl = new DirectShowVideoProbeControl; - - m_videoProbeControl->ref(); - m_session->addVideoProbe(m_videoProbeControl); - return m_videoProbeControl; - } - - if (qstrcmp(name, QCameraZoomControl_iid) == 0) - return m_zoomControl; - - if (qstrcmp(name, QImageEncoderControl_iid) == 0) - return m_imageEncoderControl; - - return nullptr; -} - -void DSCameraService::releaseControl(QMediaControl *control) -{ - if (control == m_videoRenderer) { - delete m_videoRenderer; - m_videoRenderer = nullptr; - return; - } - - if (control == m_videoProbeControl) { - m_session->removeVideoProbe(m_videoProbeControl); - if (!m_videoProbeControl->deref()) { - delete m_videoProbeControl; - m_videoProbeControl = nullptr; - } - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/camera/dscameraservice.h b/src/plugins/directshow/camera/dscameraservice.h deleted file mode 100644 index 6ea85b725..000000000 --- a/src/plugins/directshow/camera/dscameraservice.h +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DSCAMERASERVICE_H -#define DSCAMERASERVICE_H - -#include <QtCore/qobject.h> - -#include <qmediaservice.h> - -QT_BEGIN_NAMESPACE - -class DSCameraControl; -class DSCameraSession; -class DSVideoDeviceControl; -class DSImageCaptureControl; -class DSCameraViewfinderSettingsControl; -class DSCameraImageProcessingControl; -class DirectShowCameraExposureControl; -class DirectShowCameraCaptureDestinationControl; -class DirectShowCameraCaptureBufferFormatControl; -class DirectShowVideoProbeControl; -class DirectShowCameraZoomControl; -class DirectShowCameraImageEncoderControl; - -class DSCameraService : public QMediaService -{ - Q_OBJECT - -public: - DSCameraService(QObject *parent = nullptr); - ~DSCameraService() override; - - QMediaControl* requestControl(const char *name) override; - void releaseControl(QMediaControl *control) override; - -private: - DSCameraSession *m_session; - DSCameraControl *m_control; - DSVideoDeviceControl *m_videoDevice; - QMediaControl *m_videoRenderer = nullptr; - DSImageCaptureControl *m_imageCapture; - DSCameraViewfinderSettingsControl *m_viewfinderSettings; - DSCameraImageProcessingControl *m_imageProcessingControl; - DirectShowCameraExposureControl *m_exposureControl; - DirectShowCameraCaptureDestinationControl *m_captureDestinationControl; - DirectShowCameraCaptureBufferFormatControl *m_captureBufferFormatControl; - DirectShowVideoProbeControl *m_videoProbeControl = nullptr; - DirectShowCameraZoomControl *m_zoomControl; - DirectShowCameraImageEncoderControl *m_imageEncoderControl; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/directshow/camera/dscamerasession.cpp b/src/plugins/directshow/camera/dscamerasession.cpp deleted file mode 100644 index 7ceefe2c5..000000000 --- a/src/plugins/directshow/camera/dscamerasession.cpp +++ /dev/null @@ -1,1177 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtCore/qdebug.h> -#include <QFile> -#include <QtConcurrent/QtConcurrentRun> -#include <QtMultimedia/qabstractvideobuffer.h> -#include <QtMultimedia/qvideosurfaceformat.h> -#include <QtMultimedia/qcameraimagecapture.h> -#include <private/qmemoryvideobuffer_p.h> - -#include "dscamerasession.h" -#include "dsvideorenderer.h" -#include "directshowsamplegrabber.h" -#include "directshowcameraglobal.h" -#include "directshowmediatype.h" -#include "directshowutils.h" -#include "directshowvideoprobecontrol.h" - -QT_BEGIN_NAMESPACE - -DSCameraSession::DSCameraSession(QObject *parent) - : QObject(parent) -{ - connect(this, &DSCameraSession::statusChanged, - this, &DSCameraSession::updateReadyForCapture); - - m_deviceLostEventTimer.setSingleShot(true); - connect(&m_deviceLostEventTimer, &QTimer::timeout, [&]() { - IMediaEvent *pEvent = com_cast<IMediaEvent>(m_filterGraph, IID_IMediaEvent); - if (!pEvent) - return; - - long eventCode; - LONG_PTR param1; - LONG_PTR param2; - while (pEvent->GetEvent(&eventCode, ¶m1, ¶m2, 0) == S_OK) { - switch (eventCode) { - case EC_DEVICE_LOST: - unload(); - break; - default: - break; - } - - pEvent->FreeEventParams(eventCode, param1, param2); - } - - pEvent->Release(); - }); -} - -DSCameraSession::~DSCameraSession() -{ - unload(); -} - -void DSCameraSession::setSurface(QAbstractVideoSurface* surface) -{ - m_surface = surface; -} - -void DSCameraSession::setDevice(const QString &device) -{ - m_sourceDeviceName = device; -} - -QCameraViewfinderSettings DSCameraSession::viewfinderSettings() const -{ - return m_status == QCamera::ActiveStatus ? m_actualViewfinderSettings : m_viewfinderSettings; -} - -void DSCameraSession::setViewfinderSettings(const QCameraViewfinderSettings &settings) -{ - m_viewfinderSettings = settings; -} - -qreal DSCameraSession::scaledImageProcessingParameterValue( - const ImageProcessingParameterInfo &sourceValueInfo) -{ - if (sourceValueInfo.currentValue == sourceValueInfo.defaultValue) - return 0.0f; - if (sourceValueInfo.currentValue < sourceValueInfo.defaultValue) { - return ((sourceValueInfo.currentValue - sourceValueInfo.minimumValue) - / qreal(sourceValueInfo.defaultValue - sourceValueInfo.minimumValue)) - + (-1.0f); - } - return ((sourceValueInfo.currentValue - sourceValueInfo.defaultValue) - / qreal(sourceValueInfo.maximumValue - sourceValueInfo.defaultValue)); -} - -qint32 DSCameraSession::sourceImageProcessingParameterValue( - qreal scaledValue, const ImageProcessingParameterInfo &valueRange) -{ - if (qFuzzyIsNull(scaledValue)) - return valueRange.defaultValue; - if (scaledValue < 0.0f) { - return ((scaledValue - (-1.0f)) * (valueRange.defaultValue - valueRange.minimumValue)) - + valueRange.minimumValue; - } - return (scaledValue * (valueRange.maximumValue - valueRange.defaultValue)) - + valueRange.defaultValue; -} - -static QCameraImageProcessingControl::ProcessingParameter searchRelatedResultingParameter( - QCameraImageProcessingControl::ProcessingParameter sourceParameter) -{ - if (sourceParameter == QCameraImageProcessingControl::WhiteBalancePreset) - return QCameraImageProcessingControl::ColorTemperature; - return sourceParameter; -} - -bool DSCameraSession::isImageProcessingParameterSupported( - QCameraImageProcessingControl::ProcessingParameter parameter) const -{ - const QCameraImageProcessingControl::ProcessingParameter resultingParameter = - searchRelatedResultingParameter(parameter); - - return m_imageProcessingParametersInfos.contains(resultingParameter); -} - -bool DSCameraSession::isImageProcessingParameterValueSupported( - QCameraImageProcessingControl::ProcessingParameter parameter, - const QVariant &value) const -{ - const QCameraImageProcessingControl::ProcessingParameter resultingParameter = - searchRelatedResultingParameter(parameter); - - QMap<QCameraImageProcessingControl::ProcessingParameter, - ImageProcessingParameterInfo>::const_iterator sourceValueInfo = - m_imageProcessingParametersInfos.constFind(resultingParameter); - - if (sourceValueInfo == m_imageProcessingParametersInfos.constEnd()) - return false; - - switch (parameter) { - - case QCameraImageProcessingControl::WhiteBalancePreset: { - const QCameraImageProcessing::WhiteBalanceMode checkedValue = - value.value<QCameraImageProcessing::WhiteBalanceMode>(); - // Supports only the Manual and the Auto values - if (checkedValue != QCameraImageProcessing::WhiteBalanceManual - && checkedValue != QCameraImageProcessing::WhiteBalanceAuto) { - return false; - } - } - break; - - case QCameraImageProcessingControl::ColorTemperature: { - const qint32 checkedValue = value.toInt(); - if (checkedValue < (*sourceValueInfo).minimumValue - || checkedValue > (*sourceValueInfo).maximumValue) { - return false; - } - } - break; - - case QCameraImageProcessingControl::ContrastAdjustment: // falling back - case QCameraImageProcessingControl::SaturationAdjustment: // falling back - case QCameraImageProcessingControl::BrightnessAdjustment: // falling back - case QCameraImageProcessingControl::SharpeningAdjustment: { - const qint32 sourceValue = sourceImageProcessingParameterValue( - value.toReal(), (*sourceValueInfo)); - if (sourceValue < (*sourceValueInfo).minimumValue - || sourceValue > (*sourceValueInfo).maximumValue) - return false; - } - break; - - default: - return false; - } - - return true; -} - -QVariant DSCameraSession::imageProcessingParameter( - QCameraImageProcessingControl::ProcessingParameter parameter) const -{ - if (!m_graphBuilder) { - auto it = m_pendingImageProcessingParametrs.find(parameter); - return it != m_pendingImageProcessingParametrs.end() ? it.value() : QVariant(); - } - - const QCameraImageProcessingControl::ProcessingParameter resultingParameter = - searchRelatedResultingParameter(parameter); - - QMap<QCameraImageProcessingControl::ProcessingParameter, - ImageProcessingParameterInfo>::const_iterator sourceValueInfo = - m_imageProcessingParametersInfos.constFind(resultingParameter); - - if (sourceValueInfo == m_imageProcessingParametersInfos.constEnd()) - return QVariant(); - - switch (parameter) { - - case QCameraImageProcessingControl::WhiteBalancePreset: - return QVariant::fromValue<QCameraImageProcessing::WhiteBalanceMode>( - (*sourceValueInfo).capsFlags == VideoProcAmp_Flags_Auto - ? QCameraImageProcessing::WhiteBalanceAuto - : QCameraImageProcessing::WhiteBalanceManual); - - case QCameraImageProcessingControl::ColorTemperature: - return QVariant::fromValue<qint32>((*sourceValueInfo).currentValue); - - case QCameraImageProcessingControl::ContrastAdjustment: // falling back - case QCameraImageProcessingControl::SaturationAdjustment: // falling back - case QCameraImageProcessingControl::BrightnessAdjustment: // falling back - case QCameraImageProcessingControl::SharpeningAdjustment: - return scaledImageProcessingParameterValue((*sourceValueInfo)); - - default: - return QVariant(); - } -} - -void DSCameraSession::setImageProcessingParameter( - QCameraImageProcessingControl::ProcessingParameter parameter, - const QVariant &value) -{ - if (!m_graphBuilder) { - m_pendingImageProcessingParametrs.insert(parameter, value); - return; - } - - const QCameraImageProcessingControl::ProcessingParameter resultingParameter = - searchRelatedResultingParameter(parameter); - - QMap<QCameraImageProcessingControl::ProcessingParameter, - ImageProcessingParameterInfo>::iterator sourceValueInfo = - m_imageProcessingParametersInfos.find(resultingParameter); - - if (sourceValueInfo == m_imageProcessingParametersInfos.end()) - return; - - LONG sourceValue = 0; - LONG capsFlags = VideoProcAmp_Flags_Manual; - - switch (parameter) { - - case QCameraImageProcessingControl::WhiteBalancePreset: { - const QCameraImageProcessing::WhiteBalanceMode checkedValue = - value.value<QCameraImageProcessing::WhiteBalanceMode>(); - // Supports only the Manual and the Auto values - if (checkedValue == QCameraImageProcessing::WhiteBalanceManual) - capsFlags = VideoProcAmp_Flags_Manual; - else if (checkedValue == QCameraImageProcessing::WhiteBalanceAuto) - capsFlags = VideoProcAmp_Flags_Auto; - else - return; - - sourceValue = ((*sourceValueInfo).hasBeenExplicitlySet) - ? (*sourceValueInfo).currentValue - : (*sourceValueInfo).defaultValue; - } - break; - - case QCameraImageProcessingControl::ColorTemperature: - sourceValue = value.isValid() ? - value.value<qint32>() : (*sourceValueInfo).defaultValue; - capsFlags = (*sourceValueInfo).capsFlags; - break; - - case QCameraImageProcessingControl::ContrastAdjustment: // falling back - case QCameraImageProcessingControl::SaturationAdjustment: // falling back - case QCameraImageProcessingControl::BrightnessAdjustment: // falling back - case QCameraImageProcessingControl::SharpeningAdjustment: - if (value.isValid()) { - sourceValue = sourceImageProcessingParameterValue( - value.toReal(), (*sourceValueInfo)); - } else { - sourceValue = (*sourceValueInfo).defaultValue; - } - break; - - default: - return; - } - - IAMVideoProcAmp *pVideoProcAmp = nullptr; - HRESULT hr = m_graphBuilder->FindInterface( - nullptr, - nullptr, - m_sourceFilter, - IID_IAMVideoProcAmp, - reinterpret_cast<void**>(&pVideoProcAmp) - ); - - if (FAILED(hr) || !pVideoProcAmp) { - qWarning() << "failed to find the video proc amp"; - return; - } - - hr = pVideoProcAmp->Set( - (*sourceValueInfo).videoProcAmpProperty, - sourceValue, - capsFlags); - - pVideoProcAmp->Release(); - - if (FAILED(hr)) { - qWarning() << "failed to set the parameter value"; - } else { - (*sourceValueInfo).capsFlags = capsFlags; - (*sourceValueInfo).hasBeenExplicitlySet = true; - (*sourceValueInfo).currentValue = sourceValue; - } -} - -bool DSCameraSession::getCameraControlInterface(IAMCameraControl **cameraControl) const -{ - if (!m_sourceFilter) { - qCDebug(qtDirectShowPlugin, "getCameraControlInterface failed: No capture filter!"); - return false; - } - - if (!cameraControl) { - qCDebug(qtDirectShowPlugin, "getCameraControlInterface failed: Invalid out argument!"); - return false; - } - - if (FAILED(m_sourceFilter->QueryInterface(IID_IAMCameraControl, reinterpret_cast<void **>(cameraControl)))) { - qCDebug(qtDirectShowPlugin, "getCameraControlInterface failed: Querying camera control failed!"); - return false; - } - - return true; -} - -bool DSCameraSession::isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const -{ - return destination & (QCameraImageCapture::CaptureToFile | QCameraImageCapture::CaptureToBuffer); -} - -QCameraImageCapture::CaptureDestinations DSCameraSession::captureDestination() const -{ - return m_captureDestinations; -} - -void DSCameraSession::setCaptureDestination(QCameraImageCapture::CaptureDestinations destinations) -{ - if (m_captureDestinations == destinations) - return; - - m_captureDestinations = destinations; - Q_EMIT captureDestinationChanged(m_captureDestinations); -} - -void DSCameraSession::addVideoProbe(DirectShowVideoProbeControl *probe) -{ - const QMutexLocker locker(&m_probeMutex); - m_videoProbeControl = probe; -} - -void DSCameraSession::removeVideoProbe(DirectShowVideoProbeControl *probe) -{ - Q_UNUSED(probe); - Q_ASSERT(m_videoProbeControl == probe); - const QMutexLocker locker(&m_probeMutex); - m_videoProbeControl = nullptr; -} - -bool DSCameraSession::load() -{ - unload(); - - setStatus(QCamera::LoadingStatus); - - bool succeeded = createFilterGraph(); - if (succeeded) - setStatus(QCamera::LoadedStatus); - else - setStatus(QCamera::UnavailableStatus); - - return succeeded; -} - -bool DSCameraSession::unload() -{ - if (!m_graphBuilder) - return false; - - if (!stopPreview()) - return false; - - setStatus(QCamera::UnloadingStatus); - - m_needsHorizontalMirroring = false; - m_supportedViewfinderSettings.clear(); - m_supportedFormats.clear(); - SAFE_RELEASE(m_sourceFilter); - SAFE_RELEASE(m_nullRendererFilter); - SAFE_RELEASE(m_filterGraph); - SAFE_RELEASE(m_graphBuilder); - SAFE_RELEASE(m_outputPin); - - setStatus(QCamera::UnloadedStatus); - - return true; -} - -bool DSCameraSession::startPreview() -{ - if (m_previewStarted) - return true; - - if (!m_graphBuilder) - return false; - - setStatus(QCamera::StartingStatus); - - QString errorString; - HRESULT hr = S_OK; - IMediaControl* pControl = nullptr; - - if (!configurePreviewFormat()) { - errorString = tr("Failed to configure preview format"); - goto failed; - } - - if (!connectGraph()) { - errorString = tr("Failed to connect graph"); - goto failed; - } - - if (m_surface) - m_surface->start(m_previewSurfaceFormat); - - hr = m_filterGraph->QueryInterface(IID_IMediaControl, reinterpret_cast<void**>(&pControl)); - if (FAILED(hr)) { - errorString = tr("Failed to get stream control"); - goto failed; - } - hr = pControl->Run(); - pControl->Release(); - - if (FAILED(hr)) { - errorString = tr("Failed to start"); - goto failed; - } - - setStatus(QCamera::ActiveStatus); - m_previewStarted = true; - return true; - -failed: - // go back to a clean state - if (m_surface && m_surface->isActive()) - m_surface->stop(); - disconnectGraph(); - setError(QCamera::CameraError, errorString, hr); - return false; -} - -bool DSCameraSession::stopPreview() -{ - if (!m_previewStarted) - return true; - - setStatus(QCamera::StoppingStatus); - - if (m_previewSampleGrabber) - m_previewSampleGrabber->stop(); - - QString errorString; - IMediaControl* pControl = nullptr; - HRESULT hr = m_filterGraph->QueryInterface(IID_IMediaControl, - reinterpret_cast<void**>(&pControl)); - if (FAILED(hr)) { - errorString = tr("Failed to get stream control"); - goto failed; - } - - hr = pControl->Stop(); - pControl->Release(); - if (FAILED(hr)) { - errorString = tr("Failed to stop"); - goto failed; - } - - disconnectGraph(); - - m_sourceFormat.clear(); - - m_previewStarted = false; - setStatus(QCamera::LoadedStatus); - return true; - -failed: - setError(QCamera::CameraError, errorString, hr); - return false; -} - -void DSCameraSession::setError(int error, const QString &errorString, HRESULT hr) -{ - qErrnoWarning(hr, "[0x%x] %s", hr, qPrintable(errorString)); - emit cameraError(error, errorString); - setStatus(QCamera::UnloadedStatus); -} - -void DSCameraSession::setStatus(QCamera::Status status) -{ - if (m_status == status) - return; - - m_status = status; - emit statusChanged(m_status); -} - -bool DSCameraSession::isReadyForCapture() -{ - return m_readyForCapture; -} - -void DSCameraSession::updateReadyForCapture() -{ - bool isReady = (m_status == QCamera::ActiveStatus && m_imageCaptureFileName.isEmpty()); - if (isReady != m_readyForCapture) { - m_readyForCapture = isReady; - emit readyForCaptureChanged(isReady); - } -} - -int DSCameraSession::captureImage(const QString &fileName) -{ - ++m_imageIdCounter; - - if (!m_readyForCapture) { - emit captureError(m_imageIdCounter, QCameraImageCapture::NotReadyError, - tr("Camera not ready for capture")); - return m_imageIdCounter; - } - - const QString ext = !m_imageEncoderSettings.codec().isEmpty() - ? m_imageEncoderSettings.codec().toLower() - : QLatin1String("jpg"); - m_imageCaptureFileName = m_fileNameGenerator.generateFileName(fileName, - QMediaStorageLocation::Pictures, - QLatin1String("IMG_"), - ext); - - updateReadyForCapture(); - - m_captureMutex.lock(); - m_currentImageId = m_imageIdCounter; - m_captureMutex.unlock(); - - return m_imageIdCounter; -} - -void DSCameraSession::onFrameAvailable(double time, const QByteArray &data) -{ - // !!! Not called on the main thread - Q_UNUSED(time); - - m_presentMutex.lock(); - - // In case the source produces frames faster than we can display them, - // only keep the most recent one - m_currentFrame = QVideoFrame(new QMemoryVideoBuffer(data, m_stride), - m_previewSize, - m_previewPixelFormat); - - m_presentMutex.unlock(); - - { - const QMutexLocker locker(&m_probeMutex); - if (m_currentFrame.isValid() && m_videoProbeControl) - Q_EMIT m_videoProbeControl->videoFrameProbed(m_currentFrame); - } - - // Image capture - QMutexLocker locker(&m_captureMutex); - if (m_currentImageId != -1 && !m_capturedFrame.isValid()) { - m_capturedFrame = m_currentFrame; - QMetaObject::invokeMethod(this, "imageExposed", Qt::QueuedConnection, Q_ARG(int, m_currentImageId)); - } - - QMetaObject::invokeMethod(this, "presentFrame", Qt::QueuedConnection); -} - -void DSCameraSession::presentFrame() -{ - // If no frames provided from ISampleGrabber for some time - // the device might be potentially unplugged. - m_deviceLostEventTimer.start(100); - - m_presentMutex.lock(); - - if (m_currentFrame.isValid() && m_surface) { - m_surface->present(m_currentFrame); - m_currentFrame = QVideoFrame(); - } - - m_presentMutex.unlock(); - - QImage captureImage; - const int captureId = m_currentImageId; - - m_captureMutex.lock(); - - if (m_capturedFrame.isValid()) { - - captureImage = m_capturedFrame.image(); - - const bool needsVerticalMirroring = m_previewSurfaceFormat.scanLineDirection() != QVideoSurfaceFormat::TopToBottom; - captureImage = captureImage.mirrored(m_needsHorizontalMirroring, needsVerticalMirroring); // also causes a deep copy of the data - - QtConcurrent::run(&DSCameraSession::processCapturedImage, this, - m_currentImageId, m_captureDestinations, captureImage, m_imageCaptureFileName); - - m_imageCaptureFileName.clear(); - m_currentImageId = -1; - - m_capturedFrame = QVideoFrame(); - } - - m_captureMutex.unlock(); - - if (!captureImage.isNull()) - emit imageCaptured(captureId, captureImage); - - updateReadyForCapture(); -} - -void DSCameraSession::processCapturedImage(int id, - QCameraImageCapture::CaptureDestinations captureDestinations, - const QImage &image, - const QString &path) -{ - const QString format = m_imageEncoderSettings.codec(); - if (captureDestinations & QCameraImageCapture::CaptureToFile) { - if (image.save(path, !format.isEmpty() ? format.toUtf8().constData() : "JPG")) { - Q_EMIT imageSaved(id, path); - } else { - Q_EMIT captureError(id, QCameraImageCapture::ResourceError, - tr("Could not save image to file.")); - } - } - - if (captureDestinations & QCameraImageCapture::CaptureToBuffer) - Q_EMIT imageAvailable(id, QVideoFrame(image)); -} - -bool DSCameraSession::createFilterGraph() -{ - // Previously containered in <qedit.h>. - static const CLSID cLSID_NullRenderer = { 0xC1F400A4, 0x3F08, 0x11d3, { 0x9F, 0x0B, 0x00, 0x60, 0x08, 0x03, 0x9E, 0x37 } }; - - QString errorString; - HRESULT hr; - IMoniker* pMoniker = nullptr; - ICreateDevEnum* pDevEnum = nullptr; - IEnumMoniker* pEnum = nullptr; - - // Create the filter graph - hr = CoCreateInstance(CLSID_FilterGraph, nullptr, CLSCTX_INPROC, - IID_IGraphBuilder, reinterpret_cast<void**>(&m_filterGraph)); - if (FAILED(hr)) { - errorString = tr("Failed to create filter graph"); - goto failed; - } - - // Create the capture graph builder - hr = CoCreateInstance(CLSID_CaptureGraphBuilder2, nullptr, CLSCTX_INPROC, - IID_ICaptureGraphBuilder2, - reinterpret_cast<void**>(&m_graphBuilder)); - if (FAILED(hr)) { - errorString = tr("Failed to create graph builder"); - goto failed; - } - - // Attach the filter graph to the capture graph - hr = m_graphBuilder->SetFiltergraph(m_filterGraph); - if (FAILED(hr)) { - errorString = tr("Failed to connect capture graph and filter graph"); - goto failed; - } - - // Find the Capture device - hr = CoCreateInstance(CLSID_SystemDeviceEnum, nullptr, - CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, - reinterpret_cast<void**>(&pDevEnum)); - if (SUCCEEDED(hr)) { - // Create an enumerator for the video capture category - hr = pDevEnum->CreateClassEnumerator(CLSID_VideoInputDeviceCategory, &pEnum, 0); - pDevEnum->Release(); - if (S_OK == hr) { - pEnum->Reset(); - IMalloc *mallocInterface = nullptr; - CoGetMalloc(1, (LPMALLOC*)&mallocInterface); - //go through and find all video capture devices - while (pEnum->Next(1, &pMoniker, nullptr) == S_OK) { - - BSTR strName = nullptr; - hr = pMoniker->GetDisplayName(nullptr, nullptr, &strName); - if (SUCCEEDED(hr)) { - QString output = QString::fromWCharArray(strName); - mallocInterface->Free(strName); - if (m_sourceDeviceName.contains(output)) { - hr = pMoniker->BindToObject(nullptr, nullptr, IID_IBaseFilter, - reinterpret_cast<void**>(&m_sourceFilter)); - if (SUCCEEDED(hr)) { - pMoniker->Release(); - break; - } - } - } - pMoniker->Release(); - } - mallocInterface->Release(); - if (nullptr == m_sourceFilter) - { - if (m_sourceDeviceName.contains(QLatin1String("default"))) - { - pEnum->Reset(); - // still have to loop to discard bind to storage failure case - while (pEnum->Next(1, &pMoniker, nullptr) == S_OK) { - IPropertyBag *pPropBag = nullptr; - - hr = pMoniker->BindToStorage(nullptr, nullptr, IID_IPropertyBag, - reinterpret_cast<void**>(&pPropBag)); - if (FAILED(hr)) { - pMoniker->Release(); - continue; // Don't panic yet - } - - // No need to get the description, just grab it - - hr = pMoniker->BindToObject(nullptr, nullptr, IID_IBaseFilter, - reinterpret_cast<void**>(&m_sourceFilter)); - pPropBag->Release(); - pMoniker->Release(); - if (SUCCEEDED(hr)) - break; // done, stop looping through - qWarning("Object bind failed"); - } - } - } - pEnum->Release(); - } - } - - if (!m_sourceFilter) { - errorString = tr("No capture device found"); - goto failed; - } - - if (!DirectShowUtils::getPin(m_sourceFilter, PINDIR_OUTPUT, PIN_CATEGORY_CAPTURE, &m_outputPin, &hr)) - qWarning() << "Failed to get the pin for the video control:" << hr; - - // Sample grabber filter - if (!m_previewSampleGrabber) { - m_previewSampleGrabber = new DirectShowSampleGrabber(this); - connect(m_previewSampleGrabber, &DirectShowSampleGrabber::bufferAvailable, - this, &DSCameraSession::onFrameAvailable, Qt::DirectConnection); - } - - - // Null renderer. Input connected to the sample grabber's output. Simply - // discard the samples it receives. - hr = CoCreateInstance(cLSID_NullRenderer, nullptr, CLSCTX_INPROC, - IID_IBaseFilter, (void**)&m_nullRendererFilter); - if (FAILED(hr)) { - errorString = tr("Failed to create null renderer"); - goto failed; - } - - updateSourceCapabilities(); - - return true; - -failed: - m_needsHorizontalMirroring = false; - SAFE_RELEASE(m_sourceFilter); - SAFE_RELEASE(m_nullRendererFilter); - SAFE_RELEASE(m_filterGraph); - SAFE_RELEASE(m_graphBuilder); - setError(QCamera::CameraError, errorString, hr); - - return false; -} - -bool DSCameraSession::configurePreviewFormat() -{ - // Resolve viewfinder settings - int settingsIndex = 0; - const QSize captureResolution = m_imageEncoderSettings.resolution(); - const QSize resolution = captureResolution.isValid() ? captureResolution : m_viewfinderSettings.resolution(); - QCameraViewfinderSettings resolvedViewfinderSettings; - for (const QCameraViewfinderSettings &s : qAsConst(m_supportedViewfinderSettings)) { - if ((resolution.isEmpty() || resolution == s.resolution()) - && (qFuzzyIsNull(m_viewfinderSettings.minimumFrameRate()) || qFuzzyCompare((float)m_viewfinderSettings.minimumFrameRate(), (float)s.minimumFrameRate())) - && (qFuzzyIsNull(m_viewfinderSettings.maximumFrameRate()) || qFuzzyCompare((float)m_viewfinderSettings.maximumFrameRate(), (float)s.maximumFrameRate())) - && (m_viewfinderSettings.pixelFormat() == QVideoFrame::Format_Invalid || m_viewfinderSettings.pixelFormat() == s.pixelFormat()) - && (m_viewfinderSettings.pixelAspectRatio().isEmpty() || m_viewfinderSettings.pixelAspectRatio() == s.pixelAspectRatio())) { - resolvedViewfinderSettings = s; - break; - } - ++settingsIndex; - } - - if (resolvedViewfinderSettings.isNull()) { - qWarning("Invalid viewfinder settings"); - return false; - } - - m_actualViewfinderSettings = resolvedViewfinderSettings; - - m_sourceFormat = m_supportedFormats[settingsIndex]; - // Set frame rate. - // We don't care about the minimumFrameRate, DirectShow only allows to set an - // average frame rate, so set that to the maximumFrameRate. - VIDEOINFOHEADER *videoInfo = reinterpret_cast<VIDEOINFOHEADER*>(m_sourceFormat->pbFormat); - videoInfo->AvgTimePerFrame = 10000000 / resolvedViewfinderSettings.maximumFrameRate(); - - m_previewPixelFormat = resolvedViewfinderSettings.pixelFormat(); - const AM_MEDIA_TYPE *resolvedGrabberFormat = &m_sourceFormat; - - if (m_surface) { - const auto surfaceFormats = m_surface->supportedPixelFormats(QAbstractVideoBuffer::NoHandle); - if (!surfaceFormats.contains(m_previewPixelFormat)) { - if (surfaceFormats.contains(QVideoFrame::Format_RGB32)) { - // As a fallback, we support RGB32, if the capture source doesn't support - // that format, the graph builder will automatically insert a - // converter (when possible). - - static const AM_MEDIA_TYPE rgb32GrabberFormat { MEDIATYPE_Video, MEDIASUBTYPE_ARGB32, 0, 0, 0, FORMAT_VideoInfo, nullptr, 0, nullptr}; - resolvedGrabberFormat = &rgb32GrabberFormat; - m_previewPixelFormat = QVideoFrame::Format_RGB32; - - } else { - qWarning() << "Video surface needs to support at least RGB32 pixel format"; - return false; - } - } - } - - m_previewSize = resolvedViewfinderSettings.resolution(); - m_previewSurfaceFormat = QVideoSurfaceFormat(m_previewSize, - m_previewPixelFormat, - QAbstractVideoBuffer::NoHandle); - m_previewSurfaceFormat.setScanLineDirection(DirectShowMediaType::scanLineDirection(m_previewPixelFormat, videoInfo->bmiHeader)); - m_stride = DirectShowMediaType::bytesPerLine(m_previewSurfaceFormat); - - HRESULT hr; - IAMStreamConfig* pConfig = nullptr; - hr = m_graphBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, - m_sourceFilter, IID_IAMStreamConfig, - reinterpret_cast<void**>(&pConfig)); - if (FAILED(hr)) { - qWarning() << "Failed to get config for capture device"; - return false; - } - - hr = pConfig->SetFormat(&m_sourceFormat); - - pConfig->Release(); - - if (FAILED(hr)) { - qWarning() << "Unable to set video format on capture device"; - return false; - } - - if (!m_previewSampleGrabber->setMediaType(resolvedGrabberFormat)) - return false; - - m_previewSampleGrabber->start(DirectShowSampleGrabber::CallbackMethod::BufferCB); - - return true; -} - -void DSCameraSession::updateImageProcessingParametersInfos() -{ - if (!m_graphBuilder) { - qWarning() << "failed to access to the graph builder"; - return; - } - - IAMVideoProcAmp *pVideoProcAmp = nullptr; - const HRESULT hr = m_graphBuilder->FindInterface( - nullptr, - nullptr, - m_sourceFilter, - IID_IAMVideoProcAmp, - reinterpret_cast<void**>(&pVideoProcAmp) - ); - - if (FAILED(hr) || !pVideoProcAmp) { - qWarning() << "failed to find the video proc amp"; - return; - } - - for (int property = VideoProcAmp_Brightness; property <= VideoProcAmp_Gain; ++property) { - - QCameraImageProcessingControl::ProcessingParameter processingParameter; // not initialized - - switch (property) { - case VideoProcAmp_Brightness: - processingParameter = QCameraImageProcessingControl::BrightnessAdjustment; - break; - case VideoProcAmp_Contrast: - processingParameter = QCameraImageProcessingControl::ContrastAdjustment; - break; - case VideoProcAmp_Saturation: - processingParameter = QCameraImageProcessingControl::SaturationAdjustment; - break; - case VideoProcAmp_Sharpness: - processingParameter = QCameraImageProcessingControl::SharpeningAdjustment; - break; - case VideoProcAmp_WhiteBalance: - processingParameter = QCameraImageProcessingControl::ColorTemperature; - break; - default: // unsupported or not implemented yet parameter - continue; - } - - ImageProcessingParameterInfo sourceValueInfo; - LONG steppingDelta = 0; - - HRESULT hr = pVideoProcAmp->GetRange( - property, - &sourceValueInfo.minimumValue, - &sourceValueInfo.maximumValue, - &steppingDelta, - &sourceValueInfo.defaultValue, - &sourceValueInfo.capsFlags); - - if (FAILED(hr)) - continue; - - hr = pVideoProcAmp->Get( - property, - &sourceValueInfo.currentValue, - &sourceValueInfo.capsFlags); - - if (FAILED(hr)) - continue; - - sourceValueInfo.videoProcAmpProperty = static_cast<VideoProcAmpProperty>(property); - - m_imageProcessingParametersInfos.insert(processingParameter, sourceValueInfo); - } - - pVideoProcAmp->Release(); - - for (auto it = m_pendingImageProcessingParametrs.cbegin(); - it != m_pendingImageProcessingParametrs.cend(); - ++it) { - setImageProcessingParameter(it.key(), it.value()); - } - m_pendingImageProcessingParametrs.clear(); -} - -bool DSCameraSession::connectGraph() -{ - HRESULT hr = m_filterGraph->AddFilter(m_sourceFilter, L"Capture Filter"); - if (FAILED(hr)) { - qWarning() << "failed to add capture filter to graph"; - return false; - } - - if (FAILED(m_filterGraph->AddFilter(m_previewSampleGrabber->filter(), L"Sample Grabber"))) { - qWarning() << "failed to add sample grabber to graph"; - return false; - } - - hr = m_filterGraph->AddFilter(m_nullRendererFilter, L"Null Renderer"); - if (FAILED(hr)) { - qWarning() << "failed to add null renderer to graph"; - return false; - } - - hr = m_graphBuilder->RenderStream(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, - m_sourceFilter, - m_previewSampleGrabber->filter(), - m_nullRendererFilter); - if (FAILED(hr)) { - qWarning() << "Graph failed to connect filters" << hr; - return false; - } - - return true; -} - -void DSCameraSession::disconnectGraph() -{ - // To avoid increasing the memory usage every time the graph is re-connected it's - // important that all filters are released; also the ones added by the "Intelligent Connect". - IEnumFilters *enumFilters = nullptr; - if (SUCCEEDED(m_filterGraph->EnumFilters(&enumFilters))) { - IBaseFilter *filter = nullptr; - while (enumFilters->Next(1, &filter, nullptr) == S_OK) { - m_filterGraph->RemoveFilter(filter); - enumFilters->Reset(); - filter->Release(); - } - enumFilters->Release(); - } -} - -static bool qt_frameRateRangeGreaterThan(const QCamera::FrameRateRange &r1, const QCamera::FrameRateRange &r2) -{ - return r1.maximumFrameRate > r2.maximumFrameRate; -} - -void DSCameraSession::updateSourceCapabilities() -{ - HRESULT hr; - AM_MEDIA_TYPE *pmt = nullptr; - VIDEOINFOHEADER *pvi = nullptr; - VIDEO_STREAM_CONFIG_CAPS scc; - IAMStreamConfig* pConfig = nullptr; - - m_supportedViewfinderSettings.clear(); - m_needsHorizontalMirroring = false; - m_supportedFormats.clear(); - m_imageProcessingParametersInfos.clear(); - - IAMVideoControl *pVideoControl = nullptr; - hr = m_graphBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, - m_sourceFilter, IID_IAMVideoControl, - reinterpret_cast<void**>(&pVideoControl)); - if (FAILED(hr)) { - qWarning() << "Failed to get the video control"; - } else if (m_outputPin) { - long supportedModes; - hr = pVideoControl->GetCaps(m_outputPin, &supportedModes); - if (FAILED(hr)) { - qWarning() << "Failed to get the supported modes of the video control"; - } else if (supportedModes & VideoControlFlag_FlipHorizontal) { - long mode; - hr = pVideoControl->GetMode(m_outputPin, &mode); - if (FAILED(hr)) - qWarning() << "Failed to get the mode of the video control"; - else if (supportedModes & VideoControlFlag_FlipHorizontal) - m_needsHorizontalMirroring = (mode & VideoControlFlag_FlipHorizontal); - } - pVideoControl->Release(); - } - - hr = m_graphBuilder->FindInterface(&PIN_CATEGORY_CAPTURE, &MEDIATYPE_Video, - m_sourceFilter, IID_IAMStreamConfig, - reinterpret_cast<void**>(&pConfig)); - if (FAILED(hr)) { - qWarning() << "failed to get config on capture device"; - return; - } - - int iCount; - int iSize; - hr = pConfig->GetNumberOfCapabilities(&iCount, &iSize); - if (FAILED(hr)) { - qWarning() << "failed to get capabilities"; - return; - } - - for (int iIndex = 0; iIndex < iCount; ++iIndex) { - hr = pConfig->GetStreamCaps(iIndex, &pmt, reinterpret_cast<BYTE*>(&scc)); - if (hr == S_OK) { - QVideoFrame::PixelFormat pixelFormat = DirectShowMediaType::pixelFormatFromType(pmt); - - if (pmt->majortype == MEDIATYPE_Video - && pmt->formattype == FORMAT_VideoInfo - && pixelFormat != QVideoFrame::Format_Invalid) { - - pvi = reinterpret_cast<VIDEOINFOHEADER*>(pmt->pbFormat); - QSize resolution(pvi->bmiHeader.biWidth, pvi->bmiHeader.biHeight); - - QList<QCamera::FrameRateRange> frameRateRanges; - - if (pVideoControl && m_outputPin) { - long listSize = 0; - LONGLONG *frameRates = nullptr; - SIZE size = { resolution.width(), resolution.height() }; - hr = pVideoControl->GetFrameRateList(m_outputPin, iIndex, size, &listSize, &frameRates); - if (hr == S_OK && listSize > 0 && frameRates) { - for (long i = 0; i < listSize; ++i) { - qreal fr = qreal(10000000) / frameRates[i]; - frameRateRanges.append(QCamera::FrameRateRange(fr, fr)); - } - - // Make sure higher frame rates come first - std::sort(frameRateRanges.begin(), frameRateRanges.end(), qt_frameRateRangeGreaterThan); - } - - CoTaskMemFree(frameRates); - } - - if (frameRateRanges.isEmpty()) { - frameRateRanges.append(QCamera::FrameRateRange(qreal(10000000) / scc.MaxFrameInterval, - qreal(10000000) / scc.MinFrameInterval)); - } - - for (const QCamera::FrameRateRange &frameRateRange : qAsConst(frameRateRanges)) { - QCameraViewfinderSettings settings; - settings.setResolution(resolution); - settings.setMinimumFrameRate(frameRateRange.minimumFrameRate); - settings.setMaximumFrameRate(frameRateRange.maximumFrameRate); - settings.setPixelFormat(pixelFormat); - settings.setPixelAspectRatio(1, 1); - m_supportedViewfinderSettings.append(settings); - m_supportedFormats.append(DirectShowMediaType(*pmt)); - } - } else { - OLECHAR *guidString = nullptr; - StringFromCLSID(pmt->subtype, &guidString); - if (guidString) - qWarning() << "Unsupported media type:" << QString::fromWCharArray(guidString); - ::CoTaskMemFree(guidString); - } - - DirectShowMediaType::deleteType(pmt); - } - } - - pConfig->Release(); - - updateImageProcessingParametersInfos(); -} - -QList<QSize> DSCameraSession::supportedResolutions(bool *continuous) const -{ - if (continuous) - *continuous = false; - - QList<QSize> res; - for (auto &settings : m_supportedViewfinderSettings) { - auto size = settings.resolution(); - if (!res.contains(size)) - res << size; - } - - std::sort(res.begin(), res.end(), [](const QSize &r1, const QSize &r2) { - return qlonglong(r1.width()) * r1.height() < qlonglong(r2.width()) * r2.height(); - }); - - return res; -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/camera/dscamerasession.h b/src/plugins/directshow/camera/dscamerasession.h deleted file mode 100644 index 9f88163b9..000000000 --- a/src/plugins/directshow/camera/dscamerasession.h +++ /dev/null @@ -1,242 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DSCAMERASESSION_H -#define DSCAMERASESSION_H - -#include <QtCore/qobject.h> -#include <QTime> -#include <QUrl> -#include <QMutex> -#include <QTimer> -#include <qcamera.h> -#include <QtMultimedia/qvideoframe.h> -#include <QtMultimedia/qabstractvideosurface.h> -#include <QtMultimedia/qvideosurfaceformat.h> -#include <QtMultimedia/qcameraimageprocessingcontrol.h> -#include <QtMultimedia/qcameraimagecapture.h> -#include <QtMultimedia/qmediaencodersettings.h> -#include <private/qmediastoragelocation_p.h> - -#include <tchar.h> -#include <dshow.h> -#include <objbase.h> -#include <initguid.h> -#include "directshowmediatype.h" -#ifdef Q_CC_MSVC -# pragma comment(lib, "strmiids.lib") -# pragma comment(lib, "ole32.lib") -#endif // Q_CC_MSVC -#include <windows.h> - -#ifdef Q_CC_MSVC -# pragma include_alias("dxtrans.h","qedit.h") -#endif // Q_CC_MSVC -#define __IDxtCompositor_INTERFACE_DEFINED__ -#define __IDxtAlphaSetter_INTERFACE_DEFINED__ -#define __IDxtJpeg_INTERFACE_DEFINED__ -#define __IDxtKey_INTERFACE_DEFINED__ - -struct ICaptureGraphBuilder2; - -QT_BEGIN_NAMESPACE - -class DirectShowSampleGrabber; -class DirectShowVideoProbeControl; - -class DSCameraSession : public QObject -{ - Q_OBJECT -public: - DSCameraSession(QObject *parent = nullptr); - ~DSCameraSession() override; - - QCamera::Status status() const { return m_status; } - - void setDevice(const QString &device); - - bool load(); - bool unload(); - bool startPreview(); - bool stopPreview(); - - bool isReadyForCapture(); - int captureImage(const QString &fileName); - - void setSurface(QAbstractVideoSurface* surface); - - QCameraViewfinderSettings viewfinderSettings() const; - void setViewfinderSettings(const QCameraViewfinderSettings &settings); - - QList<QCameraViewfinderSettings> supportedViewfinderSettings() const - { return m_supportedViewfinderSettings; } - - bool isImageProcessingParameterSupported( - QCameraImageProcessingControl::ProcessingParameter) const; - - bool isImageProcessingParameterValueSupported( - QCameraImageProcessingControl::ProcessingParameter, - const QVariant &) const; - - QVariant imageProcessingParameter( - QCameraImageProcessingControl::ProcessingParameter) const; - - void setImageProcessingParameter( - QCameraImageProcessingControl::ProcessingParameter, - const QVariant &); - - bool getCameraControlInterface(IAMCameraControl **cameraControl) const; - - bool isCaptureDestinationSupported(QCameraImageCapture::CaptureDestinations destination) const; - QCameraImageCapture::CaptureDestinations captureDestination() const; - void setCaptureDestination(QCameraImageCapture::CaptureDestinations destinations); - - void addVideoProbe(DirectShowVideoProbeControl *probe); - void removeVideoProbe(DirectShowVideoProbeControl *probe); - - QList<QSize> supportedResolutions(bool *continuous) const; - QImageEncoderSettings imageEncoderSettings() const { return m_imageEncoderSettings; } - void setImageEncoderSettings(const QImageEncoderSettings &settings) - { m_imageEncoderSettings = settings; } - -Q_SIGNALS: - void statusChanged(QCamera::Status); - void imageExposed(int id); - void imageCaptured(int id, const QImage &preview); - void imageSaved(int id, const QString &fileName); - void imageAvailable(int id, const QVideoFrame &buffer); - void readyForCaptureChanged(bool); - void captureError(int id, int error, const QString &errorString); - void captureDestinationChanged(QCameraImageCapture::CaptureDestinations); - void cameraError(int error, const QString &errorString); - -private Q_SLOTS: - void presentFrame(); - void updateReadyForCapture(); - -private: - struct ImageProcessingParameterInfo - { - LONG minimumValue = 0; - LONG maximumValue = 0; - LONG defaultValue = 0; - LONG currentValue = 0; - LONG capsFlags = 0; - bool hasBeenExplicitlySet = false; - VideoProcAmpProperty videoProcAmpProperty = VideoProcAmp_Brightness; - }; - - void setStatus(QCamera::Status status); - - void onFrameAvailable(double time, const QByteArray &data); - void processCapturedImage(int id, QCameraImageCapture::CaptureDestinations captureDestinations, const QImage &image, const QString &path); - - bool createFilterGraph(); - bool connectGraph(); - void disconnectGraph(); - void updateSourceCapabilities(); - bool configurePreviewFormat(); - void updateImageProcessingParametersInfos(); - void setError(int error, const QString &errorString, HRESULT hr); - - // These static functions are used for scaling of adjustable parameters, - // which have the ranges from -1.0 to +1.0 in the QCameraImageProcessing API. - static qreal scaledImageProcessingParameterValue( - const ImageProcessingParameterInfo &sourceValueInfo); - static qint32 sourceImageProcessingParameterValue( - qreal scaledValue, const ImageProcessingParameterInfo &sourceValueInfo); - - QMutex m_presentMutex; - QMutex m_captureMutex; - - ICaptureGraphBuilder2* m_graphBuilder = nullptr; - IGraphBuilder* m_filterGraph = nullptr; - - // Source (camera) - QString m_sourceDeviceName = QLatin1String("default"); - IBaseFilter* m_sourceFilter = nullptr; - bool m_needsHorizontalMirroring = false; - QList<DirectShowMediaType> m_supportedFormats; - QList<QCameraViewfinderSettings> m_supportedViewfinderSettings; - DirectShowMediaType m_sourceFormat; - QMap<QCameraImageProcessingControl::ProcessingParameter, ImageProcessingParameterInfo> m_imageProcessingParametersInfos; - - // Preview - DirectShowSampleGrabber *m_previewSampleGrabber = nullptr; - IBaseFilter *m_nullRendererFilter = nullptr; - QVideoFrame m_currentFrame; - bool m_previewStarted = false; - QAbstractVideoSurface* m_surface = nullptr; - QVideoSurfaceFormat m_previewSurfaceFormat; - QVideoFrame::PixelFormat m_previewPixelFormat = QVideoFrame::Format_RGB32; - QSize m_previewSize; - int m_stride = -1; - QCameraViewfinderSettings m_viewfinderSettings; - QCameraViewfinderSettings m_actualViewfinderSettings; - - // Image capture - QString m_imageCaptureFileName; - QMediaStorageLocation m_fileNameGenerator; - bool m_readyForCapture = false; - int m_imageIdCounter = 0; - int m_currentImageId = -1; - QVideoFrame m_capturedFrame; - QCameraImageCapture::CaptureDestinations m_captureDestinations = QCameraImageCapture::CaptureToFile; - - // Video probe - QMutex m_probeMutex; - DirectShowVideoProbeControl *m_videoProbeControl = nullptr; - - QImageEncoderSettings m_imageEncoderSettings; - - // Internal state - QCamera::Status m_status = QCamera::UnloadedStatus; - QTimer m_deviceLostEventTimer; - - QMap<QCameraImageProcessingControl::ProcessingParameter, QVariant> m_pendingImageProcessingParametrs; - - IPin *m_outputPin = nullptr; - - friend class SampleGrabberCallbackPrivate; -}; - -QT_END_NAMESPACE - - -#endif diff --git a/src/plugins/directshow/camera/dscameraviewfindersettingscontrol.cpp b/src/plugins/directshow/camera/dscameraviewfindersettingscontrol.cpp deleted file mode 100644 index 655a47d07..000000000 --- a/src/plugins/directshow/camera/dscameraviewfindersettingscontrol.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "dscameraviewfindersettingscontrol.h" -#include "dscamerasession.h" - -QT_BEGIN_NAMESPACE - -DSCameraViewfinderSettingsControl::DSCameraViewfinderSettingsControl(DSCameraSession *session) - : QCameraViewfinderSettingsControl2(session) - , m_session(session) -{ -} - -QList<QCameraViewfinderSettings> DSCameraViewfinderSettingsControl::supportedViewfinderSettings() const -{ - return m_session->supportedViewfinderSettings(); -} - -QCameraViewfinderSettings DSCameraViewfinderSettingsControl::viewfinderSettings() const -{ - return m_session->viewfinderSettings(); -} - -void DSCameraViewfinderSettingsControl::setViewfinderSettings(const QCameraViewfinderSettings &settings) -{ - m_session->setViewfinderSettings(settings); -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/camera/dscameraviewfindersettingscontrol.h b/src/plugins/directshow/camera/dscameraviewfindersettingscontrol.h deleted file mode 100644 index a2b646edf..000000000 --- a/src/plugins/directshow/camera/dscameraviewfindersettingscontrol.h +++ /dev/null @@ -1,65 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DSCAMERAVIEWFINDERSETTINGSCONTROL_H -#define DSCAMERAVIEWFINDERSETTINGSCONTROL_H - -#include <qcameraviewfindersettingscontrol.h> - -QT_BEGIN_NAMESPACE - -class DSCameraSession; - -class DSCameraViewfinderSettingsControl : public QCameraViewfinderSettingsControl2 -{ -public: - DSCameraViewfinderSettingsControl(DSCameraSession *session); - - QList<QCameraViewfinderSettings> supportedViewfinderSettings() const override; - - QCameraViewfinderSettings viewfinderSettings() const override; - void setViewfinderSettings(const QCameraViewfinderSettings &settings) override; - -private: - DSCameraSession *m_session; -}; - -QT_END_NAMESPACE - -#endif // DSCAMERAVIEWFINDERSETTINGSCONTROL_H diff --git a/src/plugins/directshow/camera/dsimagecapturecontrol.cpp b/src/plugins/directshow/camera/dsimagecapturecontrol.cpp deleted file mode 100644 index e4d2eee30..000000000 --- a/src/plugins/directshow/camera/dsimagecapturecontrol.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtCore/QDebug> - -#include "dsimagecapturecontrol.h" - -QT_BEGIN_NAMESPACE - -DSImageCaptureControl::DSImageCaptureControl(DSCameraSession *session) - : QCameraImageCaptureControl(session) - , m_session(session) -{ - connect(m_session, &DSCameraSession::imageExposed, - this, &DSImageCaptureControl::imageExposed); - connect(m_session, &DSCameraSession::imageCaptured, - this, &DSImageCaptureControl::imageCaptured); - connect(m_session, &DSCameraSession::imageSaved, - this, &DSImageCaptureControl::imageSaved); - connect(m_session, &DSCameraSession::readyForCaptureChanged, - this, &DSImageCaptureControl::readyForCaptureChanged); - connect(m_session, &DSCameraSession::captureError, - this, &DSImageCaptureControl::error); - connect(m_session, &DSCameraSession::imageAvailable, - this, &DSImageCaptureControl::imageAvailable); -} - -DSImageCaptureControl::~DSImageCaptureControl() = default; - -bool DSImageCaptureControl::isReadyForCapture() const -{ - return m_session->isReadyForCapture(); -} - -int DSImageCaptureControl::capture(const QString &fileName) -{ - return m_session->captureImage(fileName); -} - -QCameraImageCapture::DriveMode DSImageCaptureControl::driveMode() const -{ - return QCameraImageCapture::SingleImageCapture; -} - -void DSImageCaptureControl::setDriveMode(QCameraImageCapture::DriveMode mode) -{ - if (mode != QCameraImageCapture::SingleImageCapture) - qWarning("Drive mode not supported."); -} - -QT_END_NAMESPACE - diff --git a/src/plugins/directshow/camera/dsimagecapturecontrol.h b/src/plugins/directshow/camera/dsimagecapturecontrol.h deleted file mode 100644 index c619de1a1..000000000 --- a/src/plugins/directshow/camera/dsimagecapturecontrol.h +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DSIMAGECAPTURECONTROL_H -#define DSIMAGECAPTURECONTROL_H - -#include <qcameraimagecapturecontrol.h> -#include "dscamerasession.h" - -QT_BEGIN_NAMESPACE - -class DSImageCaptureControl : public QCameraImageCaptureControl -{ - Q_OBJECT -public: - DSImageCaptureControl(DSCameraSession *session); - ~DSImageCaptureControl() override; - - bool isReadyForCapture() const override; - int capture(const QString &fileName) override; - - QCameraImageCapture::DriveMode driveMode() const override; - void setDriveMode(QCameraImageCapture::DriveMode mode) override; - - void cancelCapture() override {} - -private: - DSCameraSession *m_session; -}; - -QT_END_NAMESPACE - -#endif // DSCAPTURECONTROL_H diff --git a/src/plugins/directshow/camera/dsvideodevicecontrol.cpp b/src/plugins/directshow/camera/dsvideodevicecontrol.cpp deleted file mode 100644 index 0f08154f1..000000000 --- a/src/plugins/directshow/camera/dsvideodevicecontrol.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QDebug> -#include <QFile> -#include <qelapsedtimer.h> - -#include "dsvideodevicecontrol.h" -#include "dscamerasession.h" - -#include <tchar.h> -#include <dshow.h> -#include <objbase.h> -#include <initguid.h> -#include <ocidl.h> -#include <string.h> - -extern const CLSID CLSID_VideoInputDeviceCategory; - -QT_BEGIN_NAMESPACE - -Q_GLOBAL_STATIC(QList<DSVideoDeviceInfo>, deviceList) - -DSVideoDeviceControl::DSVideoDeviceControl(QObject *parent) - : QVideoDeviceSelectorControl(parent) -{ - m_session = qobject_cast<DSCameraSession*>(parent); - selected = 0; -} - -int DSVideoDeviceControl::deviceCount() const -{ - updateDevices(); - return deviceList->count(); -} - -QString DSVideoDeviceControl::deviceName(int index) const -{ - updateDevices(); - - if (index >= 0 && index <= deviceList->count()) - return QString::fromUtf8(deviceList->at(index).first.constData()); - - return QString(); -} - -QString DSVideoDeviceControl::deviceDescription(int index) const -{ - updateDevices(); - - if (index >= 0 && index <= deviceList->count()) - return deviceList->at(index).second; - - return QString(); -} - -int DSVideoDeviceControl::defaultDevice() const -{ - return 0; -} - -int DSVideoDeviceControl::selectedDevice() const -{ - return selected; -} - -void DSVideoDeviceControl::setSelectedDevice(int index) -{ - updateDevices(); - - if (index >= 0 && index < deviceList->count()) { - if (m_session) { - QString device = deviceList->at(index).first; - if (device.startsWith("ds:")) - device.remove(0,3); - m_session->setDevice(device); - } - selected = index; - } -} - -const QList<DSVideoDeviceInfo> &DSVideoDeviceControl::availableDevices() -{ - updateDevices(); - return *deviceList; -} - -void DSVideoDeviceControl::updateDevices() -{ - static QElapsedTimer timer; - if (timer.isValid() && timer.elapsed() < 500) // ms - return; - - deviceList->clear(); - - ICreateDevEnum* pDevEnum = nullptr; - IEnumMoniker* pEnum = nullptr; - // Create the System device enumerator - HRESULT hr = CoCreateInstance(CLSID_SystemDeviceEnum, nullptr, - CLSCTX_INPROC_SERVER, IID_ICreateDevEnum, - reinterpret_cast<void**>(&pDevEnum)); - if (SUCCEEDED(hr)) { - // Create the enumerator for the video capture category - hr = pDevEnum->CreateClassEnumerator( - CLSID_VideoInputDeviceCategory, &pEnum, 0); - if (S_OK == hr) { - pEnum->Reset(); - // go through and find all video capture devices - IMoniker* pMoniker = nullptr; - IMalloc *mallocInterface = nullptr; - CoGetMalloc(1, (LPMALLOC*)&mallocInterface); - while (pEnum->Next(1, &pMoniker, nullptr) == S_OK) { - BSTR strName = nullptr; - hr = pMoniker->GetDisplayName(nullptr, nullptr, &strName); - if (SUCCEEDED(hr)) { - QString output(QString::fromWCharArray(strName)); - mallocInterface->Free(strName); - - DSVideoDeviceInfo devInfo; - devInfo.first = output.toUtf8(); - - IPropertyBag *pPropBag; - hr = pMoniker->BindToStorage(nullptr, nullptr, IID_IPropertyBag, - reinterpret_cast<void**>(&pPropBag)); - if (SUCCEEDED(hr)) { - // Find the description - VARIANT varName; - varName.vt = VT_BSTR; - hr = pPropBag->Read(L"FriendlyName", &varName, nullptr); - if (SUCCEEDED(hr)) { - output = QString::fromWCharArray(varName.bstrVal); - } - pPropBag->Release(); - } - devInfo.second = output; - - deviceList->append(devInfo); - } - pMoniker->Release(); - } - mallocInterface->Release(); - pEnum->Release(); - } - pDevEnum->Release(); - } - - timer.restart(); -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/camera/dsvideodevicecontrol.h b/src/plugins/directshow/camera/dsvideodevicecontrol.h deleted file mode 100644 index 24a5b61a1..000000000 --- a/src/plugins/directshow/camera/dsvideodevicecontrol.h +++ /dev/null @@ -1,79 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DSVIDEODEVICECONTROL_H -#define DSVIDEODEVICECONTROL_H - -#include <qvideodeviceselectorcontrol.h> -#include <QStringList> - -QT_BEGIN_NAMESPACE -class DSCameraSession; - -//QTM_USE_NAMESPACE - -using DSVideoDeviceInfo = QPair<QByteArray, QString>; - -class DSVideoDeviceControl : public QVideoDeviceSelectorControl -{ - Q_OBJECT -public: - DSVideoDeviceControl(QObject *parent = nullptr); - - int deviceCount() const override; - QString deviceName(int index) const override; - QString deviceDescription(int index) const override; - int defaultDevice() const override; - int selectedDevice() const override; - - static const QList<DSVideoDeviceInfo> &availableDevices(); - -public Q_SLOTS: - void setSelectedDevice(int index) override; - -private: - static void updateDevices(); - - DSCameraSession* m_session; - int selected; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/directshow/camera/dsvideorenderer.cpp b/src/plugins/directshow/camera/dsvideorenderer.cpp deleted file mode 100644 index cde63af65..000000000 --- a/src/plugins/directshow/camera/dsvideorenderer.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtCore/qdebug.h> - -#include "dsvideorenderer.h" - -QT_BEGIN_NAMESPACE - -DSVideoRendererControl::DSVideoRendererControl(DSCameraSession* session, QObject *parent) - :QVideoRendererControl(parent), - m_session(session) -{ -} - -DSVideoRendererControl::~DSVideoRendererControl() = default; - -QAbstractVideoSurface* DSVideoRendererControl::surface() const -{ - return m_surface; -} - -void DSVideoRendererControl::setSurface(QAbstractVideoSurface *surface) -{ - m_surface = surface; - if(m_session) - m_session->setSurface(m_surface); -} - -QT_END_NAMESPACE - diff --git a/src/plugins/directshow/camera/dsvideorenderer.h b/src/plugins/directshow/camera/dsvideorenderer.h deleted file mode 100644 index a6a1f8103..000000000 --- a/src/plugins/directshow/camera/dsvideorenderer.h +++ /dev/null @@ -1,68 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DSVIDEORENDERER_H -#define DSVIDEORENDERER_H - -#include <qvideorenderercontrol.h> -#include "dscamerasession.h" - -QT_BEGIN_NAMESPACE - - -class DSVideoRendererControl : public QVideoRendererControl -{ - Q_OBJECT -public: - DSVideoRendererControl(DSCameraSession* session, QObject *parent = nullptr); - ~DSVideoRendererControl() override; - - QAbstractVideoSurface *surface() const override; - void setSurface(QAbstractVideoSurface *surface) override; - - void setSession(DSCameraSession* session); - -private: - QAbstractVideoSurface* m_surface = nullptr; - DSCameraSession* m_session; -}; - -QT_END_NAMESPACE - -#endif // DSVIDEORENDERER_H diff --git a/src/plugins/directshow/common/common.pri b/src/plugins/directshow/common/common.pri deleted file mode 100644 index 43acff8a5..000000000 --- a/src/plugins/directshow/common/common.pri +++ /dev/null @@ -1,29 +0,0 @@ -INCLUDEPATH += $$PWD - -HEADERS += \ - $$PWD/directshowbasefilter.h \ - $$PWD/directshoweventloop.h \ - $$PWD/directshowglobal.h \ - $$PWD/directshowmediatype.h \ - $$PWD/directshowmediatypeenum.h \ - $$PWD/directshowobject.h \ - $$PWD/directshowpin.h \ - $$PWD/directshowpinenum.h \ - $$PWD/directshowvideobuffer.h \ - $$PWD/directshowutils.h \ - $$PWD/directshowvideoprobecontrol.h \ - $$PWD/directshowaudioprobecontrol.h \ - $$PWD/directshowsamplegrabber.h - -SOURCES += \ - $$PWD/directshowbasefilter.cpp \ - $$PWD/directshoweventloop.cpp \ - $$PWD/directshowmediatype.cpp \ - $$PWD/directshowmediatypeenum.cpp \ - $$PWD/directshowpin.cpp \ - $$PWD/directshowpinenum.cpp \ - $$PWD/directshowvideobuffer.cpp \ - $$PWD/directshowutils.cpp \ - $$PWD/directshowvideoprobecontrol.cpp \ - $$PWD/directshowaudioprobecontrol.cpp \ - $$PWD/directshowsamplegrabber.cpp diff --git a/src/plugins/directshow/common/directshowaudioprobecontrol.cpp b/src/plugins/directshow/common/directshowaudioprobecontrol.cpp deleted file mode 100644 index 55ef70178..000000000 --- a/src/plugins/directshow/common/directshowaudioprobecontrol.cpp +++ /dev/null @@ -1,57 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowaudioprobecontrol.h" -#include "directshowglobal.h" - -QT_BEGIN_NAMESPACE - -DirectShowAudioProbeControl::DirectShowAudioProbeControl(QObject *p) - : QMediaAudioProbeControl(p) -{ - -} - -DirectShowAudioProbeControl::~DirectShowAudioProbeControl() -{ - if (m_ref.deref()) - qCWarning(qtDirectShowPlugin, "QAudioProbe control destroyed while it's still being referenced!!!"); -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/common/directshowaudioprobecontrol.h b/src/plugins/directshow/common/directshowaudioprobecontrol.h deleted file mode 100644 index 034e958fd..000000000 --- a/src/plugins/directshow/common/directshowaudioprobecontrol.h +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWAUDIOPROBECONTROL_H -#define DIRECTSHOWAUDIOPROBECONTROL_H - -#include <qmediaaudioprobecontrol.h> - -#include <QtCore/qglobal.h> - -QT_BEGIN_NAMESPACE - -class DirectShowAudioProbeControl : public QMediaAudioProbeControl -{ - Q_OBJECT -public: - explicit DirectShowAudioProbeControl(QObject *p = nullptr); - ~DirectShowAudioProbeControl() override; - - bool ref() { return m_ref.ref(); } - bool deref() { return m_ref.deref(); } -private: - QAtomicInt m_ref; -}; - -QT_END_NAMESPACE - -#endif // DIRECTSHOWAUDIOPROBECONTROL_H diff --git a/src/plugins/directshow/common/directshowbasefilter.cpp b/src/plugins/directshow/common/directshowbasefilter.cpp deleted file mode 100644 index 6099981cf..000000000 --- a/src/plugins/directshow/common/directshowbasefilter.cpp +++ /dev/null @@ -1,251 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowbasefilter.h" - -#include "directshowpinenum.h" - -#include <mutex> - -QT_BEGIN_NAMESPACE - -DirectShowBaseFilter::DirectShowBaseFilter() - = default; - -DirectShowBaseFilter::~DirectShowBaseFilter() -{ - if (m_clock) { - m_clock->Release(); - m_clock = nullptr; - } -} - -HRESULT DirectShowBaseFilter::GetClassID(CLSID *pClassID) -{ - *pClassID = CLSID_NULL; - return S_OK; -} - -HRESULT DirectShowBaseFilter::NotifyEvent(long eventCode, LONG_PTR eventParam1, LONG_PTR eventParam2) -{ - IMediaEventSink *sink = m_sink; - if (sink) { - if (eventCode == EC_COMPLETE) - eventParam2 = (LONG_PTR)(IBaseFilter*)this; - - return sink->Notify(eventCode, eventParam1, eventParam2); - } - return E_NOTIMPL; -} - -HRESULT DirectShowBaseFilter::Run(REFERENCE_TIME tStart) -{ - Q_UNUSED(tStart); - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - - m_startTime = tStart; - - if (m_state == State_Stopped){ - HRESULT hr = Pause(); - if (FAILED(hr)) - return hr; - } - - m_state = State_Running; - - return S_OK; -} - -HRESULT DirectShowBaseFilter::Pause() -{ - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - - if (m_state == State_Stopped) { - const QList<DirectShowPin *> pinList = pins(); - for (DirectShowPin *pin : pinList) { - if (pin->isConnected()) { - HRESULT hr = pin->setActive(true); - if (FAILED(hr)) - return hr; - } - } - } - - m_state = State_Paused; - - return S_OK; -} - -HRESULT DirectShowBaseFilter::Stop() -{ - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - - HRESULT hr = S_OK; - - if (m_state != State_Stopped) { - const QList<DirectShowPin *> pinList = pins(); - for (DirectShowPin *pin : pinList) { - if (pin->isConnected()) { - HRESULT hrTmp = pin->setActive(false); - if (FAILED(hrTmp) && SUCCEEDED(hr)) - hr = hrTmp; - } - } - } - - m_state = State_Stopped; - - return hr; -} - -HRESULT DirectShowBaseFilter::GetState(DWORD dwMilliSecsTimeout, FILTER_STATE *pState) -{ - Q_UNUSED(dwMilliSecsTimeout); - - if (!pState) { - return E_POINTER; - } else { - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - - *pState = m_state; - - return S_OK; - } -} - -HRESULT DirectShowBaseFilter::SetSyncSource(IReferenceClock *pClock) -{ - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - - if (m_clock) - m_clock->Release(); - - m_clock = pClock; - - if (m_clock) - m_clock->AddRef(); - - return S_OK; -} - -HRESULT DirectShowBaseFilter::GetSyncSource(IReferenceClock **ppClock) -{ - if (!ppClock) - return E_POINTER; - - if (!m_clock) { - *ppClock = nullptr; - return S_FALSE; - } - m_clock->AddRef(); - *ppClock = m_clock; - return S_OK; -} - -HRESULT DirectShowBaseFilter::EnumPins(IEnumPins **ppEnum) -{ - if (!ppEnum) - return E_POINTER; - *ppEnum = new DirectShowPinEnum(this); - return S_OK; -} - -HRESULT DirectShowBaseFilter::FindPin(LPCWSTR Id, IPin **ppPin) -{ - if (!ppPin || !Id) - return E_POINTER; - - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - const QList<DirectShowPin *> pinList = pins(); - for (DirectShowPin *pin : pinList) { - if (pin->name() == QStringView(Id)) { - pin->AddRef(); - *ppPin = pin; - return S_OK; - } - } - - *ppPin = nullptr; - return VFW_E_NOT_FOUND; -} - -HRESULT DirectShowBaseFilter::JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName) -{ - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - - m_filterName = QString::fromWCharArray(pName); - m_graph = pGraph; - m_sink = nullptr; - - if (m_graph) { - if (SUCCEEDED(m_graph->QueryInterface(IID_PPV_ARGS(&m_sink)))) - m_sink->Release(); // we don't keep a reference on it - } - - return S_OK; -} - -HRESULT DirectShowBaseFilter::QueryFilterInfo(FILTER_INFO *pInfo) -{ - if (!pInfo) - return E_POINTER; - - QString name = m_filterName; - - if (name.length() >= MAX_FILTER_NAME) - name.truncate(MAX_FILTER_NAME - 1); - - int length = name.toWCharArray(pInfo->achName); - pInfo->achName[length] = '\0'; - - if (m_graph) - m_graph->AddRef(); - - pInfo->pGraph = m_graph; - - return S_OK; -} - -HRESULT DirectShowBaseFilter::QueryVendorInfo(LPWSTR *pVendorInfo) -{ - Q_UNUSED(pVendorInfo); - return E_NOTIMPL; -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/common/directshowbasefilter.h b/src/plugins/directshow/common/directshowbasefilter.h deleted file mode 100644 index ce30891d7..000000000 --- a/src/plugins/directshow/common/directshowbasefilter.h +++ /dev/null @@ -1,95 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWBASEFILTER_H -#define DIRECTSHOWBASEFILTER_H - -#include "directshowpin.h" - -QT_BEGIN_NAMESPACE - -class DirectShowBaseFilter : public IBaseFilter -{ -public: - DirectShowBaseFilter(); - virtual ~DirectShowBaseFilter(); - - FILTER_STATE state() const { return m_state; } - HRESULT NotifyEvent(long eventCode, LONG_PTR eventParam1, LONG_PTR eventParam2); - - virtual QList<DirectShowPin *> pins() = 0; - - // IPersist - STDMETHODIMP GetClassID(CLSID *pClassID) override; - - // IMediaFilter - STDMETHODIMP Run(REFERENCE_TIME tStart) override; - STDMETHODIMP Pause() override; - STDMETHODIMP Stop() override; - - STDMETHODIMP GetState(DWORD dwMilliSecsTimeout, FILTER_STATE *pState) override; - - STDMETHODIMP SetSyncSource(IReferenceClock *pClock) override; - STDMETHODIMP GetSyncSource(IReferenceClock **ppClock) override; - - // IBaseFilter - STDMETHODIMP EnumPins(IEnumPins **ppEnum) override; - STDMETHODIMP FindPin(LPCWSTR Id, IPin **ppPin) override; - - STDMETHODIMP JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName) override; - - STDMETHODIMP QueryFilterInfo(FILTER_INFO *pInfo) override; - STDMETHODIMP QueryVendorInfo(LPWSTR *pVendorInfo) override; - -protected: - QRecursiveMutex m_mutex; - FILTER_STATE m_state = State_Stopped; - IFilterGraph *m_graph = nullptr; - IReferenceClock *m_clock = nullptr; - IMediaEventSink *m_sink = nullptr; - QString m_filterName; - REFERENCE_TIME m_startTime = 0; - -private: - Q_DISABLE_COPY(DirectShowBaseFilter) -}; - -QT_END_NAMESPACE - -#endif // DIRECTSHOWBASEFILTER_H diff --git a/src/plugins/directshow/common/directshoweventloop.cpp b/src/plugins/directshow/common/directshoweventloop.cpp deleted file mode 100644 index 692c873cf..000000000 --- a/src/plugins/directshow/common/directshoweventloop.cpp +++ /dev/null @@ -1,150 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <directshoweventloop.h> - -#include <QtCore/qcoreapplication.h> -#include <QtCore/qcoreevent.h> - -QT_BEGIN_NAMESPACE - -class DirectShowPostedEvent -{ - Q_DISABLE_COPY(DirectShowPostedEvent) -public: - DirectShowPostedEvent(QObject *receiver, QEvent *event) - : receiver(receiver) - , event(event) - { - } - - ~DirectShowPostedEvent() - { - delete event; - } - - QObject *receiver; - QEvent *event; - DirectShowPostedEvent *next = nullptr; -}; - -DirectShowEventLoop::DirectShowEventLoop(QObject *parent) - : QObject(parent) - , m_eventHandle(::CreateEvent(nullptr, FALSE, FALSE, nullptr)) - , m_waitHandle(::CreateEvent(nullptr, FALSE, FALSE, nullptr)) -{ -} - -DirectShowEventLoop::~DirectShowEventLoop() -{ - ::CloseHandle(m_eventHandle); - ::CloseHandle(m_waitHandle); - - for (DirectShowPostedEvent *post = m_postsHead; post; post = m_postsHead) { - m_postsHead = m_postsHead->next; - - delete post; - } -} - -void DirectShowEventLoop::wait(QMutex *mutex) -{ - ::ResetEvent(m_waitHandle); - - mutex->unlock(); - - HANDLE handles[] = { m_eventHandle, m_waitHandle }; - while (::WaitForMultipleObjects(2, handles, false, INFINITE) == WAIT_OBJECT_0) - processEvents(); - - mutex->lock(); -} - -void DirectShowEventLoop::wake() -{ - ::SetEvent(m_waitHandle); -} - -void DirectShowEventLoop::postEvent(QObject *receiver, QEvent *event) -{ - QMutexLocker locker(&m_mutex); - - DirectShowPostedEvent *post = new DirectShowPostedEvent(receiver, event); - - if (m_postsTail) - m_postsTail->next = post; - else - m_postsHead = post; - - m_postsTail = post; - - QCoreApplication::postEvent(this, new QEvent(QEvent::User)); - ::SetEvent(m_eventHandle); -} - -void DirectShowEventLoop::customEvent(QEvent *event) -{ - if (event->type() == QEvent::User) { - processEvents(); - } else { - QObject::customEvent(event); - } -} - -void DirectShowEventLoop::processEvents() -{ - QMutexLocker locker(&m_mutex); - - ::ResetEvent(m_eventHandle); - - while(m_postsHead) { - DirectShowPostedEvent *post = m_postsHead; - m_postsHead = m_postsHead->next; - - if (!m_postsHead) - m_postsTail = nullptr; - - locker.unlock(); - QCoreApplication::sendEvent(post->receiver, post->event); - delete post; - locker.relock(); - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/common/directshoweventloop.h b/src/plugins/directshow/common/directshoweventloop.h deleted file mode 100644 index 984bd23a4..000000000 --- a/src/plugins/directshow/common/directshoweventloop.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWEVENTLOOP_H -#define DIRECTSHOWEVENTLOOP_H - -#include <QtCore/qmutex.h> -#include <QtCore/qobject.h> -#include <QtCore/qwaitcondition.h> - -#include <qt_windows.h> - -QT_BEGIN_NAMESPACE - -class DirectShowPostedEvent; - -class DirectShowEventLoop : public QObject -{ - Q_OBJECT -public: - DirectShowEventLoop(QObject *parent = nullptr); - ~DirectShowEventLoop() override; - - void wait(QMutex *mutex); - void wake(); - - void postEvent(QObject *object, QEvent *event); - -protected: - void customEvent(QEvent *event) override; - -private: - void processEvents(); - - DirectShowPostedEvent *m_postsHead = nullptr; - DirectShowPostedEvent *m_postsTail = nullptr; - HANDLE m_eventHandle; - HANDLE m_waitHandle; - QMutex m_mutex; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/directshow/common/directshowglobal.h b/src/plugins/directshow/common/directshowglobal.h deleted file mode 100644 index 12693e4f1..000000000 --- a/src/plugins/directshow/common/directshowglobal.h +++ /dev/null @@ -1,160 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWGLOBAL_H -#define DIRECTSHOWGLOBAL_H - -#include <dshow.h> - -#include <QtCore/qglobal.h> -#include <QtCore/qloggingcategory.h> - -QT_BEGIN_NAMESPACE - -Q_DECLARE_LOGGING_CATEGORY(qtDirectShowPlugin) - -QT_END_NAMESPACE - -template <typename T> T *com_cast(IUnknown *unknown, const IID &iid) -{ - T *iface = nullptr; - return unknown && unknown->QueryInterface(iid, reinterpret_cast<void **>(&iface)) == S_OK - ? iface - : nullptr; -} - -template <typename T> T *com_new(const IID &clsid) -{ - T *object = nullptr; - return CoCreateInstance( - clsid, - nullptr, - CLSCTX_INPROC_SERVER, - IID_PPV_ARGS(&object)) == S_OK - ? object - : nullptr; -} - -template <typename T> T *com_new(const IID &clsid, const IID &iid) -{ - T *object = nullptr; - return CoCreateInstance( - clsid, - nullptr, - CLSCTX_INPROC_SERVER, - iid, - reinterpret_cast<void **>(&object)) == S_OK - ? object - : nullptr; -} - -DEFINE_GUID(MEDIASUBTYPE_I420, - 0x30323449,0x0000,0x0010,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71); - -#ifndef __IFilterGraph2_INTERFACE_DEFINED__ -#define __IFilterGraph2_INTERFACE_DEFINED__ -#define INTERFACE IFilterGraph2 -DECLARE_INTERFACE_(IFilterGraph2 ,IGraphBuilder) -{ - STDMETHOD(AddSourceFilterForMoniker)(THIS_ IMoniker *, IBindCtx *, LPCWSTR,IBaseFilter **) PURE; - STDMETHOD(ReconnectEx)(THIS_ IPin *, const AM_MEDIA_TYPE *) PURE; - STDMETHOD(RenderEx)(IPin *, DWORD, DWORD *) PURE; -}; -#undef INTERFACE -#endif - -#ifndef __IAMFilterMiscFlags_INTERFACE_DEFINED__ -#define __IAMFilterMiscFlags_INTERFACE_DEFINED__ -#define INTERFACE IAMFilterMiscFlags -DECLARE_INTERFACE_(IAMFilterMiscFlags ,IUnknown) -{ - STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - STDMETHOD_(ULONG,GetMiscFlags)(THIS) PURE; -}; -#undef INTERFACE -#endif - -#ifndef __IFileSourceFilter_INTERFACE_DEFINED__ -#define __IFileSourceFilter_INTERFACE_DEFINED__ -#define INTERFACE IFileSourceFilter -DECLARE_INTERFACE_(IFileSourceFilter ,IUnknown) -{ - STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - STDMETHOD(Load)(THIS_ LPCOLESTR, const AM_MEDIA_TYPE *) PURE; - STDMETHOD(GetCurFile)(THIS_ LPOLESTR *ppszFileName, AM_MEDIA_TYPE *) PURE; -}; -#undef INTERFACE -#endif - -#ifndef __IAMOpenProgress_INTERFACE_DEFINED__ -#define __IAMOpenProgress_INTERFACE_DEFINED__ -#undef INTERFACE -#define INTERFACE IAMOpenProgress -DECLARE_INTERFACE_(IAMOpenProgress ,IUnknown) -{ - STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - STDMETHOD(QueryProgress)(THIS_ LONGLONG *, LONGLONG *) PURE; - STDMETHOD(AbortOperation)(THIS) PURE; -}; -#undef INTERFACE -#endif - -#ifndef __IFilterChain_INTERFACE_DEFINED__ -#define __IFilterChain_INTERFACE_DEFINED__ -#define INTERFACE IFilterChain -DECLARE_INTERFACE_(IFilterChain ,IUnknown) -{ - STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - STDMETHOD(StartChain)(IBaseFilter *, IBaseFilter *) PURE; - STDMETHOD(PauseChain)(IBaseFilter *, IBaseFilter *) PURE; - STDMETHOD(StopChain)(IBaseFilter *, IBaseFilter *) PURE; - STDMETHOD(RemoveChain)(IBaseFilter *, IBaseFilter *) PURE; -}; -#undef INTERFACE -#endif - -#endif diff --git a/src/plugins/directshow/common/directshowmediatype.cpp b/src/plugins/directshow/common/directshowmediatype.cpp deleted file mode 100644 index 3429f4848..000000000 --- a/src/plugins/directshow/common/directshowmediatype.cpp +++ /dev/null @@ -1,352 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowmediatype.h" -#include "directshowglobal.h" - -#include <initguid.h> - -DEFINE_GUID(MEDIASUBTYPE_Y800, 0x30303859, 0x0000, 0x0010, 0x80, 0x00, - 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); - -namespace -{ - struct TypeLookup - { - QVideoFrame::PixelFormat pixelFormat; - GUID mediaType; - }; - - static const TypeLookup qt_typeLookup[] = - { - { QVideoFrame::Format_ARGB32, MEDIASUBTYPE_ARGB32 }, - { QVideoFrame::Format_RGB32, MEDIASUBTYPE_RGB32 }, - { QVideoFrame::Format_BGR24, MEDIASUBTYPE_RGB24 }, - { QVideoFrame::Format_RGB565, MEDIASUBTYPE_RGB565 }, - { QVideoFrame::Format_RGB555, MEDIASUBTYPE_RGB555 }, - { QVideoFrame::Format_AYUV444, MEDIASUBTYPE_AYUV }, - { QVideoFrame::Format_YUYV, MEDIASUBTYPE_YUY2 }, - { QVideoFrame::Format_UYVY, MEDIASUBTYPE_UYVY }, - { QVideoFrame::Format_IMC1, MEDIASUBTYPE_IMC1 }, - { QVideoFrame::Format_IMC2, MEDIASUBTYPE_IMC2 }, - { QVideoFrame::Format_IMC3, MEDIASUBTYPE_IMC3 }, - { QVideoFrame::Format_IMC4, MEDIASUBTYPE_IMC4 }, - { QVideoFrame::Format_YV12, MEDIASUBTYPE_YV12 }, - { QVideoFrame::Format_NV12, MEDIASUBTYPE_NV12 }, - { QVideoFrame::Format_YUV420P, MEDIASUBTYPE_IYUV }, - { QVideoFrame::Format_YUV420P, MEDIASUBTYPE_I420 }, - { QVideoFrame::Format_Jpeg, MEDIASUBTYPE_MJPG }, - { QVideoFrame::Format_Y8, MEDIASUBTYPE_Y800 }, - }; -} - -bool DirectShowMediaType::isPartiallySpecified(const AM_MEDIA_TYPE *mediaType) -{ - return mediaType->majortype == GUID_NULL || mediaType->formattype == GUID_NULL; -} - -DirectShowMediaType::DirectShowMediaType() - : mediaType({ GUID_NULL, GUID_NULL, TRUE, FALSE, 1, GUID_NULL, nullptr, 0, nullptr}) -{ -} - -DirectShowMediaType::DirectShowMediaType(const AM_MEDIA_TYPE &type) - : DirectShowMediaType() -{ - copy(&mediaType, &type); -} - -DirectShowMediaType::DirectShowMediaType(AM_MEDIA_TYPE &&type) - : DirectShowMediaType() -{ - move(&mediaType, type); -} - -DirectShowMediaType::DirectShowMediaType(const DirectShowMediaType &other) - : DirectShowMediaType() -{ - copy(&mediaType, &other.mediaType); -} - -DirectShowMediaType::DirectShowMediaType(DirectShowMediaType &&other) noexcept - : DirectShowMediaType() -{ - move(&mediaType, other.mediaType); -} - -DirectShowMediaType &DirectShowMediaType::operator=(const DirectShowMediaType &other) -{ - copy(&mediaType, &other.mediaType); - return *this; -} - -DirectShowMediaType &DirectShowMediaType::operator=(DirectShowMediaType &&other) noexcept -{ - move(&mediaType, other.mediaType); - return *this; -} - -void DirectShowMediaType::init(AM_MEDIA_TYPE *type) -{ - Q_ASSERT(type); - SecureZeroMemory(reinterpret_cast<void *>(type), sizeof(AM_MEDIA_TYPE)); - type->lSampleSize = 1; - type->bFixedSizeSamples = TRUE; -} - -void DirectShowMediaType::copy(AM_MEDIA_TYPE *target, const AM_MEDIA_TYPE *source) -{ - if (!(target && source)) - return; - - if (target == source) - return; - - clear(*target); - - copyToUninitialized(target, source); -} - -void DirectShowMediaType::copyToUninitialized(AM_MEDIA_TYPE *target, const AM_MEDIA_TYPE *source) -{ - *target = *source; - - if (source->cbFormat > 0) { - target->pbFormat = reinterpret_cast<PBYTE>(CoTaskMemAlloc(source->cbFormat)); - memcpy(target->pbFormat, source->pbFormat, source->cbFormat); - } - if (target->pUnk) - target->pUnk->AddRef(); -} - -void DirectShowMediaType::move(AM_MEDIA_TYPE *target, AM_MEDIA_TYPE **source) -{ - if (!target || !source || !(*source)) - return; - - if (target == *source) - return; - - clear(*target); - *target = *(*source); - SecureZeroMemory(reinterpret_cast<void *>(*source), sizeof(AM_MEDIA_TYPE)); - *source = nullptr; -} - -void DirectShowMediaType::move(AM_MEDIA_TYPE *target, AM_MEDIA_TYPE &source) -{ - AM_MEDIA_TYPE *srcPtr = &source; - move(target, &srcPtr); -} - -/** - * @brief DirectShowMediaType::deleteType - Used for AM_MEDIA_TYPE structures that have - * been allocated by CoTaskMemAlloc or CreateMediaType. - * @param type - */ -void DirectShowMediaType::deleteType(AM_MEDIA_TYPE *type) -{ - if (!type) - return; - - clear(*type); - CoTaskMemFree(type); -} - -bool DirectShowMediaType::isCompatible(const AM_MEDIA_TYPE *a, const AM_MEDIA_TYPE *b) -{ - if (b->majortype != GUID_NULL && a->majortype != b->majortype) - return false; - - if (b->subtype != GUID_NULL && a->subtype != b->subtype) - return false; - - if (b->formattype != GUID_NULL) { - if (a->formattype != b->formattype) - return false; - if (a->cbFormat != b->cbFormat) - return false; - if (a->cbFormat != 0 && memcmp(a->pbFormat, b->pbFormat, a->cbFormat) != 0) - return false; - } - - return true; -} - -/** - * @brief DirectShowMediaType::clear - Clears all member data, and releases allocated buffers. - * Use this to release automatic AM_MEDIA_TYPE structures. - * @param type - */ -void DirectShowMediaType::clear(AM_MEDIA_TYPE &type) -{ - if (type.cbFormat > 0) - CoTaskMemFree(type.pbFormat); - - if (type.pUnk) - type.pUnk->Release(); - - SecureZeroMemory(&type, sizeof(type)); -} - - -GUID DirectShowMediaType::convertPixelFormat(QVideoFrame::PixelFormat format) -{ - for (const auto &lookupType : qt_typeLookup) { - if (lookupType.pixelFormat == format) - return lookupType.mediaType; - } - - return MEDIASUBTYPE_None; -} - -QVideoSurfaceFormat DirectShowMediaType::videoFormatFromType(const AM_MEDIA_TYPE *type) -{ - if (!type) - return QVideoSurfaceFormat(); - - for (const auto &lookupType : qt_typeLookup) { - if (IsEqualGUID(lookupType.mediaType, type->subtype) && type->cbFormat > 0) { - if (IsEqualGUID(type->formattype, FORMAT_VideoInfo)) { - VIDEOINFOHEADER *header = reinterpret_cast<VIDEOINFOHEADER *>(type->pbFormat); - - QVideoSurfaceFormat format( - QSize(header->bmiHeader.biWidth, qAbs(header->bmiHeader.biHeight)), - lookupType.pixelFormat); - - if (header->AvgTimePerFrame > 0) - format.setFrameRate(10000 /header->AvgTimePerFrame); - - format.setScanLineDirection(scanLineDirection(format.pixelFormat(), header->bmiHeader)); - - return format; - } - if (IsEqualGUID(type->formattype, FORMAT_VideoInfo2)) { - VIDEOINFOHEADER2 *header = reinterpret_cast<VIDEOINFOHEADER2 *>(type->pbFormat); - - QVideoSurfaceFormat format( - QSize(header->bmiHeader.biWidth, qAbs(header->bmiHeader.biHeight)), - lookupType.pixelFormat); - - if (header->AvgTimePerFrame > 0) - format.setFrameRate(10000 / header->AvgTimePerFrame); - - format.setScanLineDirection(scanLineDirection(format.pixelFormat(), header->bmiHeader)); - - return format; - } - } - } - return QVideoSurfaceFormat(); -} - -QVideoFrame::PixelFormat DirectShowMediaType::pixelFormatFromType(const AM_MEDIA_TYPE *type) -{ - if (!type) - return QVideoFrame::Format_Invalid; - - for (const auto &lookupType : qt_typeLookup) { - if (IsEqualGUID(lookupType.mediaType, type->subtype)) - return lookupType.pixelFormat; - } - - return QVideoFrame::Format_Invalid; -} - -#define PAD_TO_DWORD(x) (((x) + 3) & ~3) -int DirectShowMediaType::bytesPerLine(const QVideoSurfaceFormat &format) -{ - switch (format.pixelFormat()) { - // 32 bpp packed formats. - case QVideoFrame::Format_ARGB32: - case QVideoFrame::Format_RGB32: - case QVideoFrame::Format_AYUV444: - return format.frameWidth() * 4; - // 24 bpp packed formats. - case QVideoFrame::Format_RGB24: - case QVideoFrame::Format_BGR24: - return PAD_TO_DWORD(format.frameWidth() * 3); - // 16 bpp packed formats. - case QVideoFrame::Format_RGB565: - case QVideoFrame::Format_RGB555: - case QVideoFrame::Format_YUYV: - case QVideoFrame::Format_UYVY: - return PAD_TO_DWORD(format.frameWidth() * 2); - // Planar formats. - case QVideoFrame::Format_YV12: - case QVideoFrame::Format_YUV420P: - case QVideoFrame::Format_IMC1: - case QVideoFrame::Format_IMC2: - case QVideoFrame::Format_IMC3: - case QVideoFrame::Format_IMC4: - case QVideoFrame::Format_NV12: - return format.frameWidth(); - default: - return 0; - } -} - -QVideoSurfaceFormat::Direction DirectShowMediaType::scanLineDirection(QVideoFrame::PixelFormat pixelFormat, const BITMAPINFOHEADER &bmiHeader) -{ - /* MSDN http://msdn.microsoft.com/en-us/library/windows/desktop/dd318229(v=vs.85).aspx */ - /* For uncompressed RGB bitmaps: - * if biHeight is positive, the bitmap is a bottom-up DIB with the origin at the lower left corner. - * If biHeight is negative, the bitmap is a top-down DIB with the origin at the upper left corner. - * - * For YUV bitmaps: - * the bitmap is always top-down, regardless of the sign of biHeight. - * Decoders should offer YUV formats with postive biHeight, but for backward compatibility they should accept YUV formats with either positive or negative biHeight. - * - * For compressed formats: - * biHeight must be positive, regardless of image orientation. - */ - switch (pixelFormat) - { - case QVideoFrame::Format_ARGB32: - case QVideoFrame::Format_RGB32: - case QVideoFrame::Format_RGB24: - case QVideoFrame::Format_RGB565: - case QVideoFrame::Format_RGB555: - return bmiHeader.biHeight < 0 - ? QVideoSurfaceFormat::TopToBottom - : QVideoSurfaceFormat::BottomToTop; - default: - return QVideoSurfaceFormat::TopToBottom; - } -} diff --git a/src/plugins/directshow/common/directshowmediatype.h b/src/plugins/directshow/common/directshowmediatype.h deleted file mode 100644 index ee44329a5..000000000 --- a/src/plugins/directshow/common/directshowmediatype.h +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWMEDIATYPE_H -#define DIRECTSHOWMEDIATYPE_H - -#include <dshow.h> - -#include <qvideosurfaceformat.h> - -#include <dvdmedia.h> -#include <QtCore/qglobal.h> - -QT_BEGIN_NAMESPACE - -class DirectShowMediaType -{ -public: - DirectShowMediaType(); - DirectShowMediaType(const DirectShowMediaType &other); - DirectShowMediaType(DirectShowMediaType &&other) noexcept; - explicit DirectShowMediaType(const AM_MEDIA_TYPE &type); - explicit DirectShowMediaType(AM_MEDIA_TYPE &&type); - ~DirectShowMediaType() { clear(mediaType); } - - DirectShowMediaType &operator =(const DirectShowMediaType &other); - DirectShowMediaType &operator =(DirectShowMediaType &&other) noexcept; - - void clear() { clear(mediaType); } - - inline AM_MEDIA_TYPE *operator &() Q_DECL_NOTHROW { return &mediaType; } - inline AM_MEDIA_TYPE *operator ->() Q_DECL_NOTHROW { return &mediaType; } - - inline const AM_MEDIA_TYPE *operator &() const Q_DECL_NOTHROW { return &mediaType; } - inline const AM_MEDIA_TYPE *operator ->() const Q_DECL_NOTHROW { return &mediaType; } - - static void init(AM_MEDIA_TYPE *type); - static void copy(AM_MEDIA_TYPE *target, const AM_MEDIA_TYPE *source); - static void copyToUninitialized(AM_MEDIA_TYPE *target, const AM_MEDIA_TYPE *source); - static void move(AM_MEDIA_TYPE *target, AM_MEDIA_TYPE **source); - static void move(AM_MEDIA_TYPE *target, AM_MEDIA_TYPE &source); - static void clear(AM_MEDIA_TYPE &type); - static void deleteType(AM_MEDIA_TYPE *type); - static bool isPartiallySpecified(const AM_MEDIA_TYPE *mediaType); - static bool isCompatible(const AM_MEDIA_TYPE *a, const AM_MEDIA_TYPE *b); - static GUID convertPixelFormat(QVideoFrame::PixelFormat format); - - static QVideoSurfaceFormat videoFormatFromType(const AM_MEDIA_TYPE *type); - static QVideoFrame::PixelFormat pixelFormatFromType(const AM_MEDIA_TYPE *type); - static int bytesPerLine(const QVideoSurfaceFormat &format); - static QVideoSurfaceFormat::Direction scanLineDirection(QVideoFrame::PixelFormat pixelFormat, const BITMAPINFOHEADER &bmiHeader); - -private: - AM_MEDIA_TYPE mediaType; -}; - -Q_DECLARE_TYPEINFO(DirectShowMediaType, Q_MOVABLE_TYPE); - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/directshow/common/directshowmediatypeenum.cpp b/src/plugins/directshow/common/directshowmediatypeenum.cpp deleted file mode 100644 index 02281bb98..000000000 --- a/src/plugins/directshow/common/directshowmediatypeenum.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowmediatypeenum.h" - -#include "directshowpin.h" - -DirectShowMediaTypeEnum::DirectShowMediaTypeEnum(DirectShowPin *pin) - : m_pin(pin) - , m_mediaTypes(pin->supportedMediaTypes()) -{ - m_pin->AddRef(); -} - -DirectShowMediaTypeEnum::DirectShowMediaTypeEnum(const QList<DirectShowMediaType> &types) - : m_mediaTypes(types) -{ -} - -DirectShowMediaTypeEnum::~DirectShowMediaTypeEnum() -{ - if (m_pin) - m_pin->Release(); -} - -HRESULT DirectShowMediaTypeEnum::QueryInterface(REFIID riid, void **ppv) -{ - if (ppv == nullptr) - return E_POINTER; - if (riid == IID_IUnknown) - *ppv = static_cast<IUnknown *>(this); - else if (riid == IID_IEnumMediaTypes) - *ppv = static_cast<IEnumMediaTypes *>(this); - else - return E_NOINTERFACE; - AddRef(); - return S_OK; -} - -HRESULT DirectShowMediaTypeEnum::Next(ULONG cMediaTypes, AM_MEDIA_TYPE **ppMediaTypes, ULONG *pcFetched) -{ - if (!ppMediaTypes || (!pcFetched && cMediaTypes != 1)) - return E_POINTER; - - ULONG count = qBound<ULONG>(0, cMediaTypes, m_mediaTypes.count() - m_index); - - for (ULONG i = 0; i < count; ++i, ++m_index) { - ppMediaTypes[i] = reinterpret_cast<AM_MEDIA_TYPE *>(CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE))); - DirectShowMediaType::copyToUninitialized(ppMediaTypes[i], &m_mediaTypes.at(m_index)); - } - - if (pcFetched) - *pcFetched = count; - - return count == cMediaTypes ? S_OK : S_FALSE; -} - -HRESULT DirectShowMediaTypeEnum::Skip(ULONG cMediaTypes) -{ - m_index = qMin(int(m_index + cMediaTypes), m_mediaTypes.count()); - return m_index < m_mediaTypes.count() ? S_OK : S_FALSE; -} - -HRESULT DirectShowMediaTypeEnum::Reset() -{ - m_index = 0; - return S_OK; -} - -HRESULT DirectShowMediaTypeEnum::Clone(IEnumMediaTypes **ppEnum) -{ - if (!ppEnum) - return E_POINTER; - *ppEnum = m_pin ? new DirectShowMediaTypeEnum(m_pin) : new DirectShowMediaTypeEnum(m_mediaTypes); - return S_OK; -} - diff --git a/src/plugins/directshow/common/directshowmediatypeenum.h b/src/plugins/directshow/common/directshowmediatypeenum.h deleted file mode 100644 index a5c347004..000000000 --- a/src/plugins/directshow/common/directshowmediatypeenum.h +++ /dev/null @@ -1,77 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWMEDIATYPEENUM_H -#define DIRECTSHOWMEDIATYPEENUM_H - -#include "directshowobject.h" -#include <qlist.h> - -QT_BEGIN_NAMESPACE - -class DirectShowPin; -class DirectShowMediaType; - -class DirectShowMediaTypeEnum : public IEnumMediaTypes -{ - COM_REF_MIXIN -public: - DirectShowMediaTypeEnum(DirectShowPin *pin); - DirectShowMediaTypeEnum(const QList<DirectShowMediaType> &types); - virtual ~DirectShowMediaTypeEnum(); - - STDMETHODIMP QueryInterface(REFIID riid, void **ppv) override; - - // IEnumMediaTypes - STDMETHODIMP Next(ULONG cMediaTypes, AM_MEDIA_TYPE **ppMediaTypes, ULONG *pcFetched) override; - STDMETHODIMP Skip(ULONG cMediaTypes) override; - STDMETHODIMP Reset() override; - STDMETHODIMP Clone(IEnumMediaTypes **ppEnum) override; - -private: - Q_DISABLE_COPY(DirectShowMediaTypeEnum) - - DirectShowPin *m_pin = nullptr; - QList<DirectShowMediaType> m_mediaTypes; - int m_index = 0; -}; - -QT_END_NAMESPACE - -#endif // DIRECTSHOWMEDIATYPEENUM_H diff --git a/src/plugins/directshow/common/directshowobject.h b/src/plugins/directshow/common/directshowobject.h deleted file mode 100644 index 5a8c05a3e..000000000 --- a/src/plugins/directshow/common/directshowobject.h +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWOBJECT_H -#define DIRECTSHOWOBJECT_H - -#include "directshowglobal.h" - -QT_BEGIN_NAMESPACE - -#define COM_REF_MIXIN \ - volatile ULONG m_ref = 1; \ -public: \ - STDMETHODIMP_(ULONG) AddRef() override \ - { \ - return InterlockedIncrement(&m_ref); \ - } \ - STDMETHODIMP_(ULONG) Release() override \ - { \ - const ULONG ref = InterlockedDecrement(&m_ref); \ - if (ref == 0) \ - delete this; \ - return ref; \ - } - -QT_END_NAMESPACE - -#endif // DIRECTSHOWOBJECT_H diff --git a/src/plugins/directshow/common/directshowpin.cpp b/src/plugins/directshow/common/directshowpin.cpp deleted file mode 100644 index d80b0b08e..000000000 --- a/src/plugins/directshow/common/directshowpin.cpp +++ /dev/null @@ -1,696 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowpin.h" - -#include "directshowmediatype.h" -#include "directshowbasefilter.h" -#include "directshowmediatypeenum.h" - -#include <qdebug.h> - -#include <mutex> - -QT_BEGIN_NAMESPACE - -DirectShowPin::DirectShowPin(DirectShowBaseFilter *filter, const QString &name, PIN_DIRECTION direction) - : m_filter(filter) - , m_name(name) - , m_direction(direction) -{ -} - -DirectShowPin::~DirectShowPin() = default; - -HRESULT DirectShowPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) -{ - if (!pReceivePin) - return E_POINTER; - - HRESULT hr = E_FAIL; - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - - if (m_peerPin) - return VFW_E_ALREADY_CONNECTED; - if (m_filter->state() != State_Stopped) - return VFW_E_NOT_STOPPED; - - PIN_DIRECTION pd; - pReceivePin->QueryDirection(&pd); - if (pd == m_direction) - return VFW_E_INVALID_DIRECTION; - - if (pmt != nullptr && DirectShowMediaType::isPartiallySpecified(pmt)) { - // If the type is fully specified, use it - hr = tryConnect(pReceivePin, pmt); - } else { - IEnumMediaTypes *enumMediaTypes = nullptr; - - // First, try the receiving pin's preferred types - if (SUCCEEDED(pReceivePin->EnumMediaTypes(&enumMediaTypes))) { - hr = tryMediaTypes(pReceivePin, pmt, enumMediaTypes); - enumMediaTypes->Release(); - } - // Then, try this pin's preferred types - if (FAILED(hr) && SUCCEEDED(EnumMediaTypes(&enumMediaTypes))) { - hr = tryMediaTypes(pReceivePin, pmt, enumMediaTypes); - enumMediaTypes->Release(); - } - } - - if (FAILED(hr)) { - return ((hr != E_FAIL) && (hr != E_INVALIDARG) && (hr != VFW_E_TYPE_NOT_ACCEPTED)) - ? hr : VFW_E_NO_ACCEPTABLE_TYPES; - } - - return S_OK; -} - -HRESULT DirectShowPin::tryMediaTypes(IPin *pin, const AM_MEDIA_TYPE *partialType, IEnumMediaTypes *enumMediaTypes) -{ - HRESULT hr = enumMediaTypes->Reset(); - if (FAILED(hr)) - return hr; - - AM_MEDIA_TYPE *mediaType = nullptr; - ULONG mediaCount = 0; - HRESULT hrFailure = VFW_E_NO_ACCEPTABLE_TYPES; - - for (; enumMediaTypes->Next(1, &mediaType, &mediaCount) == S_OK;) { - - if (mediaType && (partialType == nullptr || DirectShowMediaType::isCompatible(mediaType, partialType))) { - hr = tryConnect(pin, mediaType); - - if (FAILED(hr) && (hr != E_FAIL) - && (hr != E_INVALIDARG) - && (hr != VFW_E_TYPE_NOT_ACCEPTED)) { - hrFailure = hr; - } - } - - if (mediaType) - DirectShowMediaType::deleteType(mediaType); - - if (SUCCEEDED(hr)) - return S_OK; - } - - return hrFailure; -} - -HRESULT DirectShowPin::tryConnect(IPin *pin, const AM_MEDIA_TYPE *type) -{ - if (!isMediaTypeSupported(type)) - return VFW_E_TYPE_NOT_ACCEPTED; - - m_peerPin = pin; - m_peerPin->AddRef(); - - HRESULT hr; - if (!setMediaType(type)) { - hr = VFW_E_TYPE_NOT_ACCEPTED; - } else { - hr = pin->ReceiveConnection(this, type); - if (SUCCEEDED(hr)) { - hr = completeConnection(pin); - if (FAILED(hr)) - pin->Disconnect(); - } - } - - if (FAILED(hr)) { - connectionEnded(); - m_peerPin->Release(); - m_peerPin = nullptr; - setMediaType(nullptr); - return hr; - } - - return S_OK; -} - -HRESULT DirectShowPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt) -{ - if (!pConnector || !pmt) - return E_POINTER; - - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - - if (m_peerPin) - return VFW_E_ALREADY_CONNECTED; - if (m_filter->state() != State_Stopped) - return VFW_E_NOT_STOPPED; - - PIN_DIRECTION pd; - pConnector->QueryDirection(&pd); - if (pd == m_direction) - return VFW_E_INVALID_DIRECTION; - - if (!isMediaTypeSupported(pmt)) - return VFW_E_TYPE_NOT_ACCEPTED; - - m_peerPin = pConnector; - m_peerPin->AddRef(); - - HRESULT hr; - if (!setMediaType(pmt)) - hr = VFW_E_TYPE_NOT_ACCEPTED; - else - hr = completeConnection(pConnector); - - if (FAILED(hr)) { - connectionEnded(); - m_peerPin->Release(); - m_peerPin = nullptr; - setMediaType(nullptr); - return hr; - } - - return S_OK; -} - -HRESULT DirectShowPin::Disconnect() -{ - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - - if (m_filter->state() != State_Stopped) - return VFW_E_NOT_STOPPED; - - if (m_peerPin) { - HRESULT hr = connectionEnded(); - if (FAILED(hr)) - return hr; - - m_peerPin->Release(); - m_peerPin = nullptr; - - setMediaType(nullptr); - - return S_OK; - } - - return S_FALSE; -} - -HRESULT DirectShowPin::ConnectedTo(IPin **ppPin) -{ - if (!ppPin) - return E_POINTER; - - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - if (!m_peerPin) { - *ppPin = nullptr; - return VFW_E_NOT_CONNECTED; - } - m_peerPin->AddRef(); - *ppPin = m_peerPin; - return S_OK; -} - -HRESULT DirectShowPin::ConnectionMediaType(AM_MEDIA_TYPE *pmt) -{ - if (!pmt) - return E_POINTER; - - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - if (!m_peerPin) { - DirectShowMediaType::init(pmt); - return VFW_E_NOT_CONNECTED; - } - DirectShowMediaType::copy(pmt, &m_mediaType); - return S_OK; -} - -HRESULT DirectShowPin::QueryPinInfo(PIN_INFO *pInfo) -{ - if (!pInfo) - return E_POINTER; - - pInfo->pFilter = m_filter; - if (m_filter) - m_filter->AddRef(); - pInfo->dir = m_direction; - - QString name = m_name; - if (name.length() >= MAX_PIN_NAME) - name.truncate(MAX_PIN_NAME - 1); - int length = name.toWCharArray(pInfo->achName); - pInfo->achName[length] = '\0'; - - return S_OK; -} - -HRESULT DirectShowPin::QueryId(LPWSTR *Id) -{ - if (!Id) - return E_POINTER; - const int bytes = (m_name.length() + 1) * 2; - *Id = static_cast<LPWSTR>(::CoTaskMemAlloc(bytes)); - ::memcpy(*Id, m_name.utf16(), bytes); - return S_OK; -} - -HRESULT DirectShowPin::QueryAccept(const AM_MEDIA_TYPE *pmt) -{ - if (!pmt) - return E_POINTER; - - if (!isMediaTypeSupported(pmt)) - return S_FALSE; - - return S_OK; -} - -HRESULT DirectShowPin::EnumMediaTypes(IEnumMediaTypes **ppEnum) -{ - if (!ppEnum) - return E_POINTER; - *ppEnum = new DirectShowMediaTypeEnum(this); - return S_OK; -} - -HRESULT DirectShowPin::QueryInternalConnections(IPin **apPin, ULONG *nPin) -{ - Q_UNUSED(apPin); - Q_UNUSED(nPin); - return E_NOTIMPL; -} - -HRESULT DirectShowPin::EndOfStream() -{ - return S_OK; -} - -HRESULT DirectShowPin::BeginFlush() -{ - return E_UNEXPECTED; -} - -HRESULT DirectShowPin::EndFlush() -{ - return E_UNEXPECTED; -} - -HRESULT DirectShowPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) -{ - Q_UNUSED(tStart); - Q_UNUSED(tStop); - Q_UNUSED(dRate); - return S_OK; -} - -HRESULT DirectShowPin::QueryDirection(PIN_DIRECTION *pPinDir) -{ - if (!pPinDir) - return E_POINTER; - *pPinDir = m_direction; - return S_OK; -} - -QList<DirectShowMediaType> DirectShowPin::supportedMediaTypes() -{ - return QList<DirectShowMediaType>(); -} - -bool DirectShowPin::setMediaType(const AM_MEDIA_TYPE *type) -{ - if (!type) - m_mediaType.clear(); - else - DirectShowMediaType::copy(&m_mediaType, type); - - return true; -} - -HRESULT DirectShowPin::completeConnection(IPin *pin) -{ - Q_UNUSED(pin); - return S_OK; -} - -HRESULT DirectShowPin::connectionEnded() -{ - return S_OK; -} - -HRESULT DirectShowPin::setActive(bool active) -{ - Q_UNUSED(active); - return S_OK; -} - - -/* DirectShowOutputPin */ - -DirectShowOutputPin::DirectShowOutputPin(DirectShowBaseFilter *filter, const QString &name) - : DirectShowPin(filter, name, PINDIR_OUTPUT) -{ - -} - -DirectShowOutputPin::~DirectShowOutputPin() = default; - -HRESULT DirectShowOutputPin::completeConnection(IPin *pin) -{ - if (!pin) - return E_POINTER; - - Q_ASSERT(m_inputPin == nullptr); - Q_ASSERT(m_allocator == nullptr); - - HRESULT hr = pin->QueryInterface(IID_PPV_ARGS(&m_inputPin)); - if (FAILED(hr)) - return hr; - - ALLOCATOR_PROPERTIES prop; - ZeroMemory(&prop, sizeof(prop)); - m_inputPin->GetAllocatorRequirements(&prop); - if (prop.cBuffers <= 0) - prop.cBuffers = 1; - if (prop.cbBuffer <= 0) - prop.cbBuffer = 1; - if (prop.cbAlign <= 0) - prop.cbAlign = 1; - - // Use the connected input pin's allocator if it has one - hr = m_inputPin->GetAllocator(&m_allocator); - if (SUCCEEDED(hr)) { - ALLOCATOR_PROPERTIES actualProperties; - hr = m_allocator->SetProperties(&prop, &actualProperties); - - if (SUCCEEDED(hr)) { - hr = m_inputPin->NotifyAllocator(m_allocator, FALSE); - if (SUCCEEDED(hr)) - return S_OK; - } - - m_allocator->Release(); - m_allocator = nullptr; - } - - // Otherwise, allocate its own allocator - m_allocator = com_new<IMemAllocator>(CLSID_MemoryAllocator); - if (!m_allocator) { - hr = E_OUTOFMEMORY; - } else { - ALLOCATOR_PROPERTIES actualProperties; - hr = m_allocator->SetProperties(&prop, &actualProperties); - - if (SUCCEEDED(hr)) { - hr = m_inputPin->NotifyAllocator(m_allocator, FALSE); - if (SUCCEEDED(hr)) - return S_OK; - } - - m_allocator->Release(); - m_allocator = nullptr; - } - - return hr; -} - -HRESULT DirectShowOutputPin::connectionEnded() -{ - if (m_allocator) { - HRESULT hr = m_allocator->Decommit(); - if (FAILED(hr)) - return hr; - - m_allocator->Release(); - m_allocator = nullptr; - } - - if (m_inputPin) { - m_inputPin->Release(); - m_inputPin = nullptr; - } - - return S_OK; -} - -HRESULT DirectShowOutputPin::setActive(bool active) -{ - if (!m_allocator) - return VFW_E_NO_ALLOCATOR; - - return active ? m_allocator->Commit() - : m_allocator->Decommit(); -} - -HRESULT DirectShowOutputPin::EndOfStream() -{ - return E_UNEXPECTED; -} - - -/* DirectShowInputPin */ - -DirectShowInputPin::DirectShowInputPin(DirectShowBaseFilter *filter, const QString &name) - : DirectShowPin(filter, name, PINDIR_INPUT) -{ - ZeroMemory(&m_sampleProperties, sizeof(m_sampleProperties)); -} - -DirectShowInputPin::~DirectShowInputPin() = default; - -HRESULT DirectShowInputPin::connectionEnded() -{ - if (m_allocator) { - HRESULT hr = m_allocator->Decommit(); - if (FAILED(hr)) - return hr; - - m_allocator->Release(); - m_allocator = nullptr; - } - - return S_OK; -} - -HRESULT DirectShowInputPin::setActive(bool active) -{ - if (!active) { - m_inErrorState = false; - - if (!m_allocator) - return VFW_E_NO_ALLOCATOR; - - m_flushing = false; - return m_allocator->Decommit(); - } - - return S_OK; -} - -HRESULT DirectShowInputPin::EndOfStream() -{ - if (m_filter->state() == State_Stopped) - return VFW_E_WRONG_STATE; - if (m_flushing) - return S_FALSE; - if (m_inErrorState) - return VFW_E_RUNTIME_ERROR; - - return S_OK; -} - -HRESULT DirectShowInputPin::BeginFlush() -{ - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - m_flushing = true; - return S_OK; -} - -HRESULT DirectShowInputPin::EndFlush() -{ - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - m_flushing = false; - m_inErrorState = false; - return S_OK; -} - -HRESULT DirectShowInputPin::GetAllocator(IMemAllocator **ppAllocator) -{ - if (!ppAllocator) - return E_POINTER; - - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - - if (!m_allocator) { - m_allocator = com_new<IMemAllocator>(CLSID_MemoryAllocator);; - if (!m_allocator) - return E_OUTOFMEMORY; - } - - *ppAllocator = m_allocator; - m_allocator->AddRef(); - - return S_OK; -} - -HRESULT DirectShowInputPin::NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly) -{ - Q_UNUSED(bReadOnly); - - if (!pAllocator) - return E_POINTER; - - const std::lock_guard<QRecursiveMutex> locker(m_mutex); - - if (m_allocator) - m_allocator->Release(); - - m_allocator = pAllocator; - m_allocator->AddRef(); - - return S_OK; -} - -HRESULT DirectShowInputPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps) -{ - Q_UNUSED(pProps); - return E_NOTIMPL; -} - -HRESULT DirectShowInputPin::Receive(IMediaSample *pSample) -{ - if (!pSample) - return E_POINTER; - if (m_filter->state() == State_Stopped) - return VFW_E_WRONG_STATE; - if (m_flushing) - return S_FALSE; - if (m_inErrorState) - return VFW_E_RUNTIME_ERROR; - - HRESULT hr = S_OK; - - IMediaSample2 *sample2; - if (SUCCEEDED(pSample->QueryInterface(IID_PPV_ARGS(&sample2)))) { - hr = sample2->GetProperties(sizeof(m_sampleProperties), - reinterpret_cast<PBYTE>(&m_sampleProperties)); - sample2->Release(); - if (FAILED(hr)) - return hr; - } else { - m_sampleProperties.cbData = sizeof(m_sampleProperties); - m_sampleProperties.dwTypeSpecificFlags = 0; - m_sampleProperties.dwStreamId = AM_STREAM_MEDIA; - m_sampleProperties.dwSampleFlags = 0; - if (pSample->IsDiscontinuity() == S_OK) - m_sampleProperties.dwSampleFlags |= AM_SAMPLE_DATADISCONTINUITY; - if (pSample->IsPreroll() == S_OK) - m_sampleProperties.dwSampleFlags |= AM_SAMPLE_PREROLL; - if (pSample->IsSyncPoint() == S_OK) - m_sampleProperties.dwSampleFlags |= AM_SAMPLE_SPLICEPOINT; - if (SUCCEEDED(pSample->GetTime(&m_sampleProperties.tStart, - &m_sampleProperties.tStop))) { - m_sampleProperties.dwSampleFlags |= AM_SAMPLE_TIMEVALID | AM_SAMPLE_STOPVALID; - } - if (pSample->GetMediaType(&m_sampleProperties.pMediaType) == S_OK) - m_sampleProperties.dwSampleFlags |= AM_SAMPLE_TYPECHANGED; - pSample->GetPointer(&m_sampleProperties.pbBuffer); - m_sampleProperties.lActual = pSample->GetActualDataLength(); - m_sampleProperties.cbBuffer = pSample->GetSize(); - } - - - if (!(m_sampleProperties.dwSampleFlags & AM_SAMPLE_TYPECHANGED)) - return S_OK; - - if (isMediaTypeSupported(m_sampleProperties.pMediaType)) - return S_OK; - - m_inErrorState = true; - EndOfStream(); - m_filter->NotifyEvent(EC_ERRORABORT, VFW_E_TYPE_NOT_ACCEPTED, 0); - return VFW_E_INVALIDMEDIATYPE; -} - -HRESULT DirectShowInputPin::ReceiveMultiple(IMediaSample **pSamples, long nSamples, long *nSamplesProcessed) -{ - if (!pSamples || !nSamplesProcessed) - return E_POINTER; - - HRESULT hr = S_OK; - *nSamplesProcessed = 0; - while (nSamples-- > 0) { - hr = Receive(pSamples[*nSamplesProcessed]); - if (hr != S_OK) - break; - (*nSamplesProcessed)++; - } - return hr; -} - -HRESULT DirectShowInputPin::ReceiveCanBlock() -{ - int outputPins = 0; - - const QList<DirectShowPin *> pinList = m_filter->pins(); - for (DirectShowPin *pin : pinList) { - PIN_DIRECTION pd; - HRESULT hr = pin->QueryDirection(&pd); - if (FAILED(hr)) - return hr; - - if (pd == PINDIR_OUTPUT) { - IPin *connected; - hr = pin->ConnectedTo(&connected); - if (SUCCEEDED(hr)) { - ++outputPins; - IMemInputPin *inputPin; - hr = connected->QueryInterface(IID_PPV_ARGS(&inputPin)); - connected->Release(); - if (SUCCEEDED(hr)) { - hr = inputPin->ReceiveCanBlock(); - inputPin->Release(); - if (hr != S_FALSE) - return S_OK; - } else { - return S_OK; - } - } - } - } - - return outputPins == 0 ? S_OK : S_FALSE; -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/common/directshowpin.h b/src/plugins/directshow/common/directshowpin.h deleted file mode 100644 index 160191ef3..000000000 --- a/src/plugins/directshow/common/directshowpin.h +++ /dev/null @@ -1,180 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWPIN_H -#define DIRECTSHOWPIN_H - -#include "directshowobject.h" - -#include "directshowmediatype.h" -#include <qstring.h> -#include <qmutex.h> - -QT_BEGIN_NAMESPACE - -class DirectShowBaseFilter; - -class DirectShowPin : public IPin -{ -public: - virtual ~DirectShowPin(); - - QString name() const { return m_name; } - bool isConnected() const { return m_peerPin != nullptr; } - - virtual bool isMediaTypeSupported(const AM_MEDIA_TYPE *type) = 0; - virtual QList<DirectShowMediaType> supportedMediaTypes(); - virtual bool setMediaType(const AM_MEDIA_TYPE *type); - - virtual HRESULT completeConnection(IPin *pin); - virtual HRESULT connectionEnded(); - - virtual HRESULT setActive(bool active); - - // IPin - STDMETHODIMP Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) override; - STDMETHODIMP ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt) override; - STDMETHODIMP Disconnect() override; - STDMETHODIMP ConnectedTo(IPin **ppPin) override; - - STDMETHODIMP ConnectionMediaType(AM_MEDIA_TYPE *pmt) override; - - STDMETHODIMP QueryPinInfo(PIN_INFO *pInfo) override; - STDMETHODIMP QueryId(LPWSTR *Id) override; - - STDMETHODIMP QueryAccept(const AM_MEDIA_TYPE *pmt) override; - - STDMETHODIMP EnumMediaTypes(IEnumMediaTypes **ppEnum) override; - - STDMETHODIMP QueryInternalConnections(IPin **apPin, ULONG *nPin) override; - - STDMETHODIMP EndOfStream() override; - - STDMETHODIMP BeginFlush() override; - STDMETHODIMP EndFlush() override; - - STDMETHODIMP NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) override; - - STDMETHODIMP QueryDirection(PIN_DIRECTION *pPinDir) override; - -protected: - DirectShowPin(DirectShowBaseFilter *filter, const QString &name, PIN_DIRECTION direction); - - QRecursiveMutex m_mutex; - - DirectShowBaseFilter *m_filter; - QString m_name; - PIN_DIRECTION m_direction; - - IPin *m_peerPin = nullptr; - DirectShowMediaType m_mediaType; - -private: - Q_DISABLE_COPY(DirectShowPin) - HRESULT tryMediaTypes(IPin *pin, const AM_MEDIA_TYPE *type, IEnumMediaTypes *enumMediaTypes); - HRESULT tryConnect(IPin *pin, const AM_MEDIA_TYPE *type); -}; - - -class DirectShowOutputPin : public DirectShowPin -{ -public: - ~DirectShowOutputPin() override; - - // DirectShowPin - HRESULT completeConnection(IPin *pin) override; - HRESULT connectionEnded() override; - HRESULT setActive(bool active) override; - - // IPin - STDMETHODIMP EndOfStream() override; - -protected: - DirectShowOutputPin(DirectShowBaseFilter *filter, const QString &name); - - IMemAllocator *m_allocator = nullptr; - IMemInputPin *m_inputPin = nullptr; - -private: - Q_DISABLE_COPY(DirectShowOutputPin) -}; - - -class DirectShowInputPin : public DirectShowPin - , public IMemInputPin -{ -public: - ~DirectShowInputPin() override; - - const AM_SAMPLE2_PROPERTIES *currentSampleProperties() const { return &m_sampleProperties; } - - // DirectShowPin - HRESULT connectionEnded() override; - HRESULT setActive(bool active) override; - - // IPin - STDMETHODIMP EndOfStream() override; - STDMETHODIMP BeginFlush() override; - STDMETHODIMP EndFlush() override; - - // IMemInputPin - STDMETHODIMP GetAllocator(IMemAllocator **ppAllocator) override; - STDMETHODIMP NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly) override; - STDMETHODIMP GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps) override; - - STDMETHODIMP Receive(IMediaSample *pSample) override; - STDMETHODIMP ReceiveMultiple(IMediaSample **pSamples, long nSamples, - long *nSamplesProcessed) override; - STDMETHODIMP ReceiveCanBlock() override; - -protected: - DirectShowInputPin(DirectShowBaseFilter *filter, const QString &name); - - IMemAllocator *m_allocator = nullptr; - bool m_flushing = false; - bool m_inErrorState = false; - AM_SAMPLE2_PROPERTIES m_sampleProperties; - -private: - Q_DISABLE_COPY(DirectShowInputPin) -}; - -QT_END_NAMESPACE - -#endif // DIRECTSHOWPIN_H diff --git a/src/plugins/directshow/common/directshowpinenum.cpp b/src/plugins/directshow/common/directshowpinenum.cpp deleted file mode 100644 index 7ba1bb6e9..000000000 --- a/src/plugins/directshow/common/directshowpinenum.cpp +++ /dev/null @@ -1,125 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowpinenum.h" -#include "directshowbasefilter.h" - -QT_BEGIN_NAMESPACE - -DirectShowPinEnum::DirectShowPinEnum(DirectShowBaseFilter *filter) - : m_filter(filter) -{ - m_filter->AddRef(); - const QList<DirectShowPin *> pinList = filter->pins(); - for (DirectShowPin *pin : pinList) { - pin->AddRef(); - m_pins.append(pin); - } -} - -DirectShowPinEnum::DirectShowPinEnum(const QList<IPin *> &pins) - : m_pins(pins) -{ - for (IPin *pin : qAsConst(m_pins)) - pin->AddRef(); -} - -DirectShowPinEnum::~DirectShowPinEnum() -{ - for (IPin *pin : qAsConst(m_pins)) - pin->Release(); - if (m_filter) - m_filter->Release(); -} - -HRESULT DirectShowPinEnum::QueryInterface(REFIID riid, void **ppv) -{ - if (ppv == nullptr) - return E_POINTER; - if (riid == IID_IUnknown) - *ppv = static_cast<IUnknown *>(this); - else if (riid == IID_IEnumPins) - *ppv = static_cast<IEnumPins *>(this); - else - return E_NOINTERFACE; - AddRef(); - return S_OK; -} - -HRESULT DirectShowPinEnum::Next(ULONG cPins, IPin **ppPins, ULONG *pcFetched) -{ - if (!ppPins || (!pcFetched && cPins != 1)) - return E_POINTER; - - ULONG count = qBound<ULONG>(0, cPins, m_pins.count() - m_index); - - for (ULONG i = 0; i < count; ++i, ++m_index) { - ppPins[i] = m_pins.at(m_index); - ppPins[i]->AddRef(); - } - - if (pcFetched) - *pcFetched = count; - - return count == cPins ? S_OK : S_FALSE; -} - -HRESULT DirectShowPinEnum::Skip(ULONG cPins) -{ - m_index = qMin(int(m_index + cPins), m_pins.count()); - - return m_index < m_pins.count() ? S_OK : S_FALSE; -} - -HRESULT DirectShowPinEnum::Reset() -{ - m_index = 0; - - return S_OK; -} - -HRESULT DirectShowPinEnum::Clone(IEnumPins **ppEnum) -{ - if (!ppEnum) - return E_POINTER; - *ppEnum = m_filter ? new DirectShowPinEnum(m_filter) : new DirectShowPinEnum(m_pins); - return S_OK; -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/common/directshowpinenum.h b/src/plugins/directshow/common/directshowpinenum.h deleted file mode 100644 index aada1a71e..000000000 --- a/src/plugins/directshow/common/directshowpinenum.h +++ /dev/null @@ -1,78 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWPINENUM_H -#define DIRECTSHOWPINENUM_H - -#include <dshow.h> - -#include <QtCore/qlist.h> -#include "directshowpin.h" - -QT_BEGIN_NAMESPACE - -class DirectShowBaseFilter; - -class DirectShowPinEnum : public IEnumPins -{ - COM_REF_MIXIN -public: - DirectShowPinEnum(DirectShowBaseFilter *filter); - DirectShowPinEnum(const QList<IPin *> &pins); - virtual ~DirectShowPinEnum(); - - STDMETHODIMP QueryInterface(REFIID riid, void **ppv) override; - - // IEnumPins - STDMETHODIMP Next(ULONG cPins, IPin **ppPins, ULONG *pcFetched) override; - STDMETHODIMP Skip(ULONG cPins) override; - STDMETHODIMP Reset() override; - STDMETHODIMP Clone(IEnumPins **ppEnum) override; - -private: - Q_DISABLE_COPY(DirectShowPinEnum) - - DirectShowBaseFilter *m_filter = nullptr; - QList<IPin *> m_pins; - int m_index = 0; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/directshow/common/directshowsamplegrabber.cpp b/src/plugins/directshow/common/directshowsamplegrabber.cpp deleted file mode 100644 index a9e74f9db..000000000 --- a/src/plugins/directshow/common/directshowsamplegrabber.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowsamplegrabber.h" - -#include "directshowglobal.h" -#include "directshowutils.h" - - -QT_BEGIN_NAMESPACE - -// Previously contained in <qedit.h>. -static const IID iID_ISampleGrabber = { 0x6B652FFF, 0x11FE, 0x4fce, { 0x92, 0xAD, 0x02, 0x66, 0xB5, 0xD7, 0xC7, 0x8F } }; -static const CLSID cLSID_SampleGrabber = { 0xC1F400A0, 0x3F08, 0x11d3, { 0x9F, 0x0B, 0x00, 0x60, 0x08, 0x03, 0x9E, 0x37 } }; - -class SampleGrabberCallbackPrivate : public ISampleGrabberCB -{ - Q_DISABLE_COPY(SampleGrabberCallbackPrivate) -public: - explicit SampleGrabberCallbackPrivate(DirectShowSampleGrabber *grabber) - : m_ref(1) - , m_grabber(grabber) - { } - - virtual ~SampleGrabberCallbackPrivate() = default; - - STDMETHODIMP_(ULONG) AddRef() override - { - return InterlockedIncrement(&m_ref); - } - - STDMETHODIMP_(ULONG) Release() override - { - ULONG ref = InterlockedDecrement(&m_ref); - if (ref == 0) - delete this; - return ref; - } - - STDMETHODIMP QueryInterface(REFIID riid, void **ppvObject) override - { - if (nullptr == ppvObject) - return E_POINTER; - - if (riid == IID_IUnknown /*__uuidof(IUnknown) */ ) { - AddRef(); - *ppvObject = static_cast<IUnknown *>(this); - return S_OK; - } - if (riid == IID_ISampleGrabberCB /*__uuidof(ISampleGrabberCB)*/ ) { - AddRef(); - *ppvObject = static_cast<ISampleGrabberCB *>(this); - return S_OK; - } - return E_NOTIMPL; - } - - STDMETHODIMP SampleCB(double time, IMediaSample *mediaSample) override - { - if (m_grabber) - Q_EMIT m_grabber->sampleAvailable(time, mediaSample); - - return S_OK; - } - - STDMETHODIMP BufferCB(double time, BYTE *buffer, long bufferLen) override - { - if (m_grabber) { - // Deep copy, the data might be modified or freed after the callback returns - QByteArray data(reinterpret_cast<const char *>(buffer), bufferLen); - Q_EMIT m_grabber->bufferAvailable(time, data); - } - return S_OK; - } - -private: - ULONG m_ref; - DirectShowSampleGrabber *m_grabber; -}; - -DirectShowSampleGrabber::DirectShowSampleGrabber(QObject *p) - : QObject(p) -{ - // Create sample grabber filter - HRESULT hr = CoCreateInstance(cLSID_SampleGrabber, nullptr, CLSCTX_INPROC, iID_ISampleGrabber, reinterpret_cast<void **>(&m_sampleGrabber)); - - if (FAILED(hr)) { - qCWarning(qtDirectShowPlugin, "Failed to create sample grabber"); - return; - } - - hr = m_sampleGrabber->QueryInterface(IID_IBaseFilter, reinterpret_cast<void **>(&m_filter)); - if (FAILED(hr)) - qCWarning(qtDirectShowPlugin, "Failed to get base filter interface"); -} - -DirectShowSampleGrabber::~DirectShowSampleGrabber() -{ - stop(); - SAFE_RELEASE(m_sampleGabberCb); - SAFE_RELEASE(m_filter); - SAFE_RELEASE(m_sampleGrabber); -} - -void DirectShowSampleGrabber::stop() -{ - if (!m_sampleGrabber) - return; - - if (FAILED(m_sampleGrabber->SetCallback(nullptr, static_cast<long>(m_callbackType)))) { - qCWarning(qtDirectShowPlugin, "Failed to stop sample grabber callback"); - return; - } -} - -bool DirectShowSampleGrabber::getConnectedMediaType(AM_MEDIA_TYPE *mediaType) -{ - Q_ASSERT(mediaType); - - if (!isValid()) - return false; - - if (FAILED(m_sampleGrabber->GetConnectedMediaType(mediaType))) { - qCWarning(qtDirectShowPlugin, "Failed to retrieve the connected media type"); - return false; - } - - return true; -} - -bool DirectShowSampleGrabber::setMediaType(const AM_MEDIA_TYPE *mediaType) -{ - Q_ASSERT(mediaType); - - if (FAILED(m_sampleGrabber->SetMediaType(mediaType))) { - qCWarning(qtDirectShowPlugin, "Failed to set media type"); - return false; - } - - return true; -} - -void DirectShowSampleGrabber::start(DirectShowSampleGrabber::CallbackMethod method, - bool oneShot, - bool bufferSamples) -{ - if (!m_sampleGrabber) - return; - - stop(); - - if (!m_sampleGabberCb) - m_sampleGabberCb = new SampleGrabberCallbackPrivate(this); - - m_callbackType = method; - m_sampleGrabber->SetCallback(m_sampleGabberCb, static_cast<long>(method)); - m_sampleGrabber->SetOneShot(oneShot); - m_sampleGrabber->SetBufferSamples(bufferSamples); -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/common/directshowsamplegrabber.h b/src/plugins/directshow/common/directshowsamplegrabber.h deleted file mode 100644 index 5fc61de14..000000000 --- a/src/plugins/directshow/common/directshowsamplegrabber.h +++ /dev/null @@ -1,89 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWSAMPLEGRABBER_H -#define DIRECTSHOWSAMPLEGRABBER_H - -#include <QtCore/qglobal.h> -#include <QtCore/qobject.h> - -// TODO: Fix this. -#include <directshowcameraglobal.h> - -QT_BEGIN_NAMESPACE - -class SampleGrabberCallbackPrivate; - -class DirectShowSampleGrabber : public QObject -{ - Q_OBJECT -public: - DirectShowSampleGrabber(QObject *p = nullptr); - ~DirectShowSampleGrabber(); - - // 0 = ISampleGrabberCB::SampleCB, 1 = ISampleGrabberCB::BufferCB - enum class CallbackMethod : long - { - SampleCB, - BufferCB - }; - - bool isValid() const { return m_filter && m_sampleGrabber; } - bool getConnectedMediaType(AM_MEDIA_TYPE *mediaType); - bool setMediaType(const AM_MEDIA_TYPE *mediaType); - - void stop(); - void start(CallbackMethod method, bool oneShot = false, bool bufferSamples = false); - - IBaseFilter *filter() const { return m_filter; } - -Q_SIGNALS: - void sampleAvailable(double time, IMediaSample *sample); - void bufferAvailable(double time, const QByteArray &data); - -private: - IBaseFilter *m_filter = nullptr; - ISampleGrabber *m_sampleGrabber = nullptr; - SampleGrabberCallbackPrivate *m_sampleGabberCb = nullptr; - CallbackMethod m_callbackType= CallbackMethod::BufferCB; -}; - -QT_END_NAMESPACE - -#endif // DIRECTSHOWSAMPLEGRABBER_H diff --git a/src/plugins/directshow/common/directshowutils.cpp b/src/plugins/directshow/common/directshowutils.cpp deleted file mode 100644 index 9222ad779..000000000 --- a/src/plugins/directshow/common/directshowutils.cpp +++ /dev/null @@ -1,346 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowutils.h" - -QT_BEGIN_NAMESPACE - -/** - * @brief DirectShowUtils::isPinConnected - * @param pin - * @param hrOut - * @return - */ -bool DirectShowUtils::isPinConnected(IPin *pin, HRESULT *hrOut) -{ - IPin *connectedPin = nullptr; - const ScopedSafeRelease<IPin> releasePin { &connectedPin }; - HRESULT hr = S_OK; - if (!hrOut) - hrOut = &hr; - - *hrOut = pin->ConnectedTo(&connectedPin); - if (*hrOut == VFW_E_NOT_CONNECTED) { // Not an error in this case - *hrOut = S_OK; - return false; - } - - if (FAILED(*hrOut)) { - qCDebug(qtDirectShowPlugin, "Querying pin connection failed!"); - return false; - } - - return true; -} - -/** - * @brief DirectShowUtils::hasPinDirection - * @param pin - * @param direction - * @param hrOut - * @return - */ -bool DirectShowUtils::hasPinDirection(IPin *pin, PIN_DIRECTION direction, HRESULT *hrOut) -{ - PIN_DIRECTION pinDir; - HRESULT hr = S_OK; - if (!hrOut) - hrOut = &hr; - - *hrOut = pin->QueryDirection(&pinDir); - - if (FAILED(*hrOut)) { - qCDebug(qtDirectShowPlugin, "Querying pin direction failed!"); - return false; - } - - return (pinDir == direction); -} - -bool pinMatchesCategory(IPin* pPin, REFGUID category) -{ - bool found = false; - IKsPropertySet *pKs = nullptr; - DirectShowUtils::ScopedSafeRelease<IKsPropertySet> ks_property { &pKs }; - HRESULT hr = pPin->QueryInterface(IID_PPV_ARGS(&pKs)); - - if (SUCCEEDED(hr)) { - GUID pin_category; - DWORD return_value; - hr = pKs->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, NULL, 0, - &pin_category, sizeof(pin_category), &return_value); - if (SUCCEEDED(hr) && (return_value == sizeof(pin_category))) - found = (pin_category == category); - } - - return found; -} - -/** - * @brief DirectShowUtils::getPin - * @param filter - * @param pinDirection - * @param pin - * @param hrOut - * @return - */ -bool DirectShowUtils::getPin(IBaseFilter *filter, PIN_DIRECTION pinDirection, REFGUID category, IPin **pin, HRESULT *hrOut) -{ - IEnumPins *enumPins = nullptr; - const ScopedSafeRelease<IEnumPins> releaseEnumPins { &enumPins }; - HRESULT hr S_OK; - if (!hrOut) - hrOut = &hr; - - *hrOut = filter->EnumPins(&enumPins); - if (FAILED(*hrOut)) { - qCDebug(qtDirectShowPlugin, "Unable to retrieve pins from the filter!"); - return false; - } - - enumPins->Reset(); - IPin *nextPin = nullptr; - while (enumPins->Next(1, &nextPin, nullptr) == S_OK) { - const ScopedSafeRelease<IPin> releasePin { &nextPin }; - PIN_DIRECTION currentPinDir; - *hrOut = nextPin->QueryDirection(¤tPinDir); - if (currentPinDir == pinDirection) { - if (category == GUID_NULL || pinMatchesCategory(nextPin, category)) { - *pin = nextPin; - (*pin)->AddRef(); - return true; - } - } - } - - return false; -} - -/** - * @brief DirectShowUtils::matchPin - * @param pin - * @param pinDirection - * @param shouldBeConnected - * @param hrOut - * @return - */ -bool DirectShowUtils::matchPin(IPin *pin, PIN_DIRECTION pinDirection, BOOL shouldBeConnected, HRESULT *hrOut) -{ - HRESULT hr = S_OK; - if (!hrOut) - hrOut = &hr; - - const BOOL isConnected = isPinConnected(pin, hrOut); - if (FAILED(*hrOut)) // Error reason will already be logged, so just return. - return false; - - if (isConnected == shouldBeConnected) - return hasPinDirection(pin, pinDirection, hrOut); - - return false; -} - -/** - * @brief DirectShowUtils::findUnconnectedPin - * @param filter - * @param pinDirection - * @param pin - * @param hrOut - * @return - */ -bool DirectShowUtils::findUnconnectedPin(IBaseFilter *filter, PIN_DIRECTION pinDirection, IPin **pin, HRESULT *hrOut) -{ - HRESULT hr = S_OK; - if (!hrOut) - hrOut = &hr; - - IEnumPins *enumPins = nullptr; - const ScopedSafeRelease<IEnumPins> releaseEnumPins { &enumPins }; - *hrOut = filter->EnumPins(&enumPins); - if (FAILED(*hrOut)) { - qCDebug(qtDirectShowPlugin, "Unable to retrieve pins from the DS filter"); - return false; - } - - IPin *nextPin = nullptr; - while (S_OK == enumPins->Next(1, &nextPin, nullptr)) { - const ScopedSafeRelease<IPin> releaseNextPin { &nextPin }; - if (matchPin(nextPin, pinDirection, FALSE, hrOut)) { - *pin = nextPin; - (*pin)->AddRef(); - return true; - } - } - - qCDebug(qtDirectShowPlugin, "No unconnected pins found"); - *hrOut = VFW_E_NOT_FOUND; - - return false; -} - -/** - * @brief DirectShowUtils::connectFilters - Attempts to connect \a outputPin to \a filter - * @param graph - * @param outputPin - * @param filter - * @param hrOut - * @return - */ -bool DirectShowUtils::connectFilters(IGraphBuilder *graph, IPin *outputPin, IBaseFilter *filter, HRESULT *hrOut) -{ - - // Find an input pin on the downstream filter. - HRESULT hr = S_OK; - if (!hrOut) - hrOut = &hr; - - IPin *inputPin = nullptr; - const ScopedSafeRelease<IPin> releaseInputPin { &inputPin }; - if (!findUnconnectedPin(filter, PINDIR_INPUT, &inputPin, hrOut)) - return false; - - - // Try to connect them. - *hrOut = graph->Connect(outputPin, inputPin); - if (FAILED(*hrOut)) { - qCDebug(qtDirectShowPlugin, "Unable to connect output pin to filter!"); - return false; - } - - return true; -} - -/** - * @brief DirectShowUtils::connectFilters - Attempts to connect \a filter to \a inputPin. - * @param graph - * @param filter - * @param inputPin - * @param hrOut - * @return - */ -bool DirectShowUtils::connectFilters(IGraphBuilder *graph, IBaseFilter *filter, IPin *inputPin, HRESULT *hrOut) -{ - HRESULT hr = S_OK; - if (!hrOut) - hrOut = &hr; - - IPin *outputPin = nullptr; - const ScopedSafeRelease<IPin> releaseOutputPin { &outputPin }; - // Find an output pin on the upstream filter. - if (findUnconnectedPin(filter, PINDIR_OUTPUT, &outputPin, hrOut)) - return false; - - *hrOut = graph->Connect(outputPin, inputPin); - if (FAILED(*hrOut)) { - qCDebug(qtDirectShowPlugin, "Unable to connect filter to input pin!"); - return false; - } - - return true; -} - -/** - * @brief DirectShowUtils::connectFilters - Attempts to connect the \a upstreamFilter to \a downstreamFilter. - * @param graph - * @param upstreamFilter - * @param downstreamFilter - * @param autoConnect - If set to true all filters in the graph will be considered. - * @param hrOut - * @return true if the the filters were connected, false otherwise. - */ -bool DirectShowUtils::connectFilters(IGraphBuilder *graph, - IBaseFilter *upstreamFilter, - IBaseFilter *downstreamFilter, - bool autoConnect, - HRESULT *hrOut) -{ - HRESULT hr = S_OK; - if (!hrOut) - hrOut = &hr; - - const auto findAndConnect = [graph, downstreamFilter, hrOut](IBaseFilter *filter) -> bool { - IPin *outputPin = nullptr; - const ScopedSafeRelease<IPin> releaseOutputPin { &outputPin }; - if (findUnconnectedPin(filter, PINDIR_OUTPUT, &outputPin, hrOut)) - return connectFilters(graph, outputPin, downstreamFilter, hrOut); - - return false; - }; - - // Try to connect to the upstream filter first. - if (findAndConnect(upstreamFilter)) - return true; - - const auto getFilters = [graph, hrOut]() -> IEnumFilters * { - IEnumFilters *f = nullptr; - *hrOut = graph->EnumFilters(&f); - return f; - }; - IEnumFilters *filters = autoConnect ? getFilters() - : nullptr; - const ScopedSafeRelease<IEnumFilters> releaseEnumFilters { &filters }; - if (!filters) { - qCDebug(qtDirectShowPlugin, "No filters found!"); - return false; - } - - IBaseFilter *nextFilter = nullptr; - while (S_OK == filters->Next(1, &nextFilter, nullptr)) { - const ScopedSafeRelease<IBaseFilter> releaseNextFilter { &nextFilter }; - if (nextFilter && findAndConnect(nextFilter)) - return true; - } - - return false; -} - -thread_local static int g_refCount = 0; -void DirectShowUtils::CoInitializeIfNeeded() -{ - if (++g_refCount == 1) - ::CoInitialize(nullptr); -} - -void DirectShowUtils::CoUninitializeIfNeeded() -{ - if (--g_refCount == 0) - ::CoUninitialize(); -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/common/directshowutils.h b/src/plugins/directshow/common/directshowutils.h deleted file mode 100644 index ec761abe6..000000000 --- a/src/plugins/directshow/common/directshowutils.h +++ /dev/null @@ -1,91 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWUTILS_H -#define DIRECTSHOWUTILS_H - -#include "directshowglobal.h" - -QT_BEGIN_NAMESPACE - -namespace DirectShowUtils -{ -template <typename T> -void safeRelease(T **iface) { - if (!iface) - return; - - if (!*iface) - return; - - (*iface)->Release(); - *iface = nullptr; -} - -template <typename T> -struct ScopedSafeRelease -{ - T **iunknown; - ~ScopedSafeRelease() - { - DirectShowUtils::safeRelease(iunknown); - } -}; - -bool getPin(IBaseFilter *filter, PIN_DIRECTION pinDirection, REFGUID category, IPin **pin, HRESULT *hrOut); -bool isPinConnected(IPin *pin, HRESULT *hrOut = nullptr); -bool hasPinDirection(IPin *pin, PIN_DIRECTION direction, HRESULT *hrOut = nullptr); -bool matchPin(IPin *pin, PIN_DIRECTION pinDirection, BOOL shouldBeConnected, HRESULT *hrOut = nullptr); -bool findUnconnectedPin(IBaseFilter *filter, PIN_DIRECTION pinDirection, IPin **pin, HRESULT *hrOut = nullptr); -bool connectFilters(IGraphBuilder *graph, IPin *outputPin, IBaseFilter *filter, HRESULT *hrOut = nullptr); -bool connectFilters(IGraphBuilder *graph, IBaseFilter *filter, IPin *inputPin, HRESULT *hrOut = nullptr); -bool connectFilters(IGraphBuilder *graph, - IBaseFilter *upstreamFilter, - IBaseFilter *downstreamFilter, - bool autoConnect = false, - HRESULT *hrOut = nullptr); - -void CoInitializeIfNeeded(); -void CoUninitializeIfNeeded(); - -} - -QT_END_NAMESPACE - -#endif // DIRECTSHOWUTILS_H diff --git a/src/plugins/directshow/common/directshowvideobuffer.cpp b/src/plugins/directshow/common/directshowvideobuffer.cpp deleted file mode 100644 index fc329f58a..000000000 --- a/src/plugins/directshow/common/directshowvideobuffer.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowvideobuffer.h" - -QT_BEGIN_NAMESPACE - -DirectShowVideoBuffer::DirectShowVideoBuffer(IMediaSample *sample, int bytesPerLine) - : QAbstractVideoBuffer(NoHandle) - , m_sample(sample) - , m_bytesPerLine(bytesPerLine) - , m_mapMode(NotMapped) -{ - m_sample->AddRef(); -} - -DirectShowVideoBuffer::~DirectShowVideoBuffer() -{ - m_sample->Release(); -} - -uchar *DirectShowVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine) -{ - if (m_mapMode == NotMapped && mode != NotMapped) { - if (numBytes) - *numBytes = m_sample->GetActualDataLength(); - - if (bytesPerLine) - *bytesPerLine = m_bytesPerLine; - - BYTE *bytes = nullptr; - - if (m_sample->GetPointer(&bytes) == S_OK) { - m_mapMode = mode; - - return reinterpret_cast<uchar *>(bytes); - } - } - return nullptr; -} - -void DirectShowVideoBuffer::unmap() -{ - m_mapMode = NotMapped; -} - -QAbstractVideoBuffer::MapMode DirectShowVideoBuffer::mapMode() const -{ - return m_mapMode; -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/common/directshowvideobuffer.h b/src/plugins/directshow/common/directshowvideobuffer.h deleted file mode 100644 index a85a3ca34..000000000 --- a/src/plugins/directshow/common/directshowvideobuffer.h +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWVIDEOBUFFER_H -#define DIRECTSHOWVIDEOBUFFER_H - -#include <dshow.h> - -#include <qabstractvideobuffer.h> - -QT_BEGIN_NAMESPACE - -class DirectShowVideoBuffer : public QAbstractVideoBuffer -{ -public: - DirectShowVideoBuffer(IMediaSample *sample, int bytesPerLine); - ~DirectShowVideoBuffer() override; - - IMediaSample *sample() { return m_sample; } - - uchar *map(MapMode mode, int *numBytes, int *bytesPerLine) override; - void unmap() override; - - MapMode mapMode() const override; - -private: - IMediaSample *m_sample; - int m_bytesPerLine; - MapMode m_mapMode; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/directshow/common/directshowvideoprobecontrol.cpp b/src/plugins/directshow/common/directshowvideoprobecontrol.cpp deleted file mode 100644 index 0e2e68864..000000000 --- a/src/plugins/directshow/common/directshowvideoprobecontrol.cpp +++ /dev/null @@ -1,69 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowvideoprobecontrol.h" -#include "directshowglobal.h" - -QT_BEGIN_NAMESPACE - -DirectShowVideoProbeControl::DirectShowVideoProbeControl(QObject *p) - : QMediaVideoProbeControl(p) -{ - -} - -DirectShowVideoProbeControl::~DirectShowVideoProbeControl() -{ - if (m_ref.deref()) - qCWarning(qtDirectShowPlugin, "QVideoProbe control destroyed while it's still being referenced!!!"); -} - -void DirectShowVideoProbeControl::probeVideoFrame(const QVideoFrame &frame) -{ - emit videoFrameProbed(frame); - m_frameProbed = true; -} - -void DirectShowVideoProbeControl::flushVideoFrame() -{ - if (m_frameProbed) - emit flush(); -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/common/directshowvideoprobecontrol.h b/src/plugins/directshow/common/directshowvideoprobecontrol.h deleted file mode 100644 index 57839f8d3..000000000 --- a/src/plugins/directshow/common/directshowvideoprobecontrol.h +++ /dev/null @@ -1,67 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWVIDEOPROBECONTROL_H -#define DIRECTSHOWVIDEOPROBECONTROL_H - -#include <qmediavideoprobecontrol.h> - -#include <QtCore/qglobal.h> - -QT_BEGIN_NAMESPACE - -class DirectShowVideoProbeControl : public QMediaVideoProbeControl -{ - Q_OBJECT -public: - explicit DirectShowVideoProbeControl(QObject *p = nullptr); - ~DirectShowVideoProbeControl(); - - bool ref() { return m_ref.ref(); } - bool deref() { return m_ref.deref(); } - void probeVideoFrame(const QVideoFrame &frame); - void flushVideoFrame(); -private: - QAtomicInt m_ref; - bool m_frameProbed = false; -}; - -QT_END_NAMESPACE - -#endif // DIRECTSHOWVIDEOPROBECONTROL_H diff --git a/src/plugins/directshow/directshow.json b/src/plugins/directshow/directshow.json deleted file mode 100644 index b1783b5ed..000000000 --- a/src/plugins/directshow/directshow.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "Keys": ["directshow"], - "Services": ["org.qt-project.qt.camera", "org.qt-project.qt.mediaplayer"] -} diff --git a/src/plugins/directshow/directshow.pro b/src/plugins/directshow/directshow.pro deleted file mode 100644 index 27bb3abb8..000000000 --- a/src/plugins/directshow/directshow.pro +++ /dev/null @@ -1,32 +0,0 @@ -TARGET = dsengine -QT += multimedia-private - -win32:!qtHaveModule(opengl)|qtConfig(dynamicgl) { - LIBS_PRIVATE += -lgdi32 -luser32 -} - -HEADERS += dsserviceplugin.h -SOURCES += dsserviceplugin.cpp - -# Remove WINVER/_WIN32_WINNT definitions added to qt_build_config.prf -# by qtbase/d57a7c41712f8627a462d893329dc3f0dbb52d32 since the multimedia -# headers of MinGW 5.3/7.1 are too broken to compile with 0x0601. -mingw { - DEFINES -= WINVER=0x0601 _WIN32_WINNT=0x0601 - DEFINES += NO_DSHOW_STRSAFE -} - -mingw { - LIBS_PRIVATE += -lamstrmid -} - -include(common/common.pri) -include(player/player.pri) -include(camera/camera.pri) - -OTHER_FILES += \ - directshow.json - -PLUGIN_TYPE = mediaservice -PLUGIN_CLASS_NAME = DSServicePlugin -load(qt_plugin) diff --git a/src/plugins/directshow/dsserviceplugin.cpp b/src/plugins/directshow/dsserviceplugin.cpp deleted file mode 100644 index 18a807fd1..000000000 --- a/src/plugins/directshow/dsserviceplugin.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtMultimedia/private/qtmultimediaglobal_p.h> -#include <dshow.h> - -#include <QtCore/qstring.h> -#include <QtCore/qdebug.h> -#include <QtCore/QFile> - -#include "directshowglobal.h" -#include "dsserviceplugin.h" - -#include "dsvideodevicecontrol.h" -#include <dshow.h> -#include "dscameraservice.h" - -#include "directshowplayerservice.h" - -#include <qmediaserviceproviderplugin.h> -#include "directshowutils.h" - -extern const CLSID CLSID_VideoInputDeviceCategory; - - -#ifndef _STRSAFE_H_INCLUDED_ -#include <tchar.h> -#endif -#include <dshow.h> -#include <objbase.h> -#include <initguid.h> -#ifdef Q_CC_MSVC -# pragma comment(lib, "strmiids.lib") -# pragma comment(lib, "ole32.lib") -#endif // Q_CC_MSVC -#include <windows.h> -#include <ocidl.h> - -QT_BEGIN_NAMESPACE -Q_LOGGING_CATEGORY(qtDirectShowPlugin, "qt.multimedia.plugins.directshow") - -QMediaService* DSServicePlugin::create(QString const& key) -{ - if (key == QLatin1String(Q_MEDIASERVICE_CAMERA)) { - DirectShowUtils::CoInitializeIfNeeded(); - return new DSCameraService; - } - - if (key == QLatin1String(Q_MEDIASERVICE_MEDIAPLAYER)) { - DirectShowUtils::CoInitializeIfNeeded(); - return new DirectShowPlayerService; - } - - return nullptr; -} - -void DSServicePlugin::release(QMediaService *service) -{ - delete service; - DirectShowUtils::CoUninitializeIfNeeded(); -} - -QMediaServiceProviderHint::Features DSServicePlugin::supportedFeatures( - const QByteArray &service) const -{ - return service == Q_MEDIASERVICE_MEDIAPLAYER - ? (QMediaServiceProviderHint::StreamPlayback | QMediaServiceProviderHint::VideoSurface) - : QMediaServiceProviderHint::Features(); -} - -QByteArray DSServicePlugin::defaultDevice(const QByteArray &service) const -{ - if (service == Q_MEDIASERVICE_CAMERA) { - DirectShowUtils::CoInitializeIfNeeded(); - const QList<DSVideoDeviceInfo> &devs = DSVideoDeviceControl::availableDevices(); - DirectShowUtils::CoUninitializeIfNeeded(); - if (!devs.isEmpty()) - return devs.first().first; - } - return QByteArray(); -} - -QList<QByteArray> DSServicePlugin::devices(const QByteArray &service) const -{ - QList<QByteArray> result; - - if (service == Q_MEDIASERVICE_CAMERA) { - DirectShowUtils::CoInitializeIfNeeded(); - const QList<DSVideoDeviceInfo> &devs = DSVideoDeviceControl::availableDevices(); - DirectShowUtils::CoUninitializeIfNeeded(); - for (const DSVideoDeviceInfo &info : devs) - result.append(info.first); - } - - return result; -} - -QString DSServicePlugin::deviceDescription(const QByteArray &service, const QByteArray &device) -{ - if (service == Q_MEDIASERVICE_CAMERA) { - DirectShowUtils::CoInitializeIfNeeded(); - const QList<DSVideoDeviceInfo> &devs = DSVideoDeviceControl::availableDevices(); - DirectShowUtils::CoUninitializeIfNeeded(); - for (const DSVideoDeviceInfo &info : devs) { - if (info.first == device) - return info.second; - } - } - return QString(); -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/dsserviceplugin.h b/src/plugins/directshow/dsserviceplugin.h deleted file mode 100644 index 55db9310c..000000000 --- a/src/plugins/directshow/dsserviceplugin.h +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DSSERVICEPLUGIN_H -#define DSSERVICEPLUGIN_H - -#include <QtMultimedia/private/qtmultimediaglobal_p.h> -#include "qmediaserviceproviderplugin.h" - -QT_BEGIN_NAMESPACE - -class DSServicePlugin - : public QMediaServiceProviderPlugin - , public QMediaServiceSupportedDevicesInterface - , public QMediaServiceDefaultDeviceInterface - , public QMediaServiceFeaturesInterface -{ - Q_OBJECT - Q_INTERFACES(QMediaServiceSupportedDevicesInterface) - Q_INTERFACES(QMediaServiceDefaultDeviceInterface) - Q_INTERFACES(QMediaServiceFeaturesInterface) - Q_PLUGIN_METADATA(IID "org.qt-project.qt.mediaserviceproviderfactory/5.0" FILE "directshow.json") - -public: - QMediaService* create(QString const& key) override; - void release(QMediaService *service) override; - - QMediaServiceProviderHint::Features supportedFeatures(const QByteArray &service) const override; - - QByteArray defaultDevice(const QByteArray &service) const override; - QList<QByteArray> devices(const QByteArray &service) const override; - QString deviceDescription(const QByteArray &service, const QByteArray &device) override; -}; - -QT_END_NAMESPACE - -#endif // DSSERVICEPLUGIN_H diff --git a/src/plugins/directshow/player/directshowaudioendpointcontrol.cpp b/src/plugins/directshow/player/directshowaudioendpointcontrol.cpp deleted file mode 100644 index f4e45cdd8..000000000 --- a/src/plugins/directshow/player/directshowaudioendpointcontrol.cpp +++ /dev/null @@ -1,161 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowaudioendpointcontrol.h" - -#include "directshowglobal.h" -#include "directshowplayerservice.h" - -QT_BEGIN_NAMESPACE - -DirectShowAudioEndpointControl::DirectShowAudioEndpointControl( - DirectShowPlayerService *service, QObject *parent) - : QAudioOutputSelectorControl(parent) - , m_service(service) -{ - if (CreateBindCtx(0, &m_bindContext) == S_OK) { - m_deviceEnumerator = com_new<ICreateDevEnum>(CLSID_SystemDeviceEnum); - - updateEndpoints(); - - setActiveOutput(m_defaultEndpoint); - } -} - -DirectShowAudioEndpointControl::~DirectShowAudioEndpointControl() -{ - for (IMoniker *moniker : qAsConst(m_devices)) - moniker->Release(); - - if (m_bindContext) - m_bindContext->Release(); - - if (m_deviceEnumerator) - m_deviceEnumerator->Release(); -} - -QList<QString> DirectShowAudioEndpointControl::availableOutputs() const -{ - return m_devices.keys(); -} - -QString DirectShowAudioEndpointControl::outputDescription(const QString &name) const -{ -#ifdef __IPropertyBag_INTERFACE_DEFINED__ - QString description; - - if (IMoniker *moniker = m_devices.value(name, 0)) { - IPropertyBag *propertyBag = nullptr; - if (SUCCEEDED(moniker->BindToStorage( - nullptr, nullptr, IID_IPropertyBag, reinterpret_cast<void **>(&propertyBag)))) { - VARIANT name; - VariantInit(&name); - if (SUCCEEDED(propertyBag->Read(L"FriendlyName", &name, nullptr))) - description = QString::fromWCharArray(name.bstrVal); - VariantClear(&name); - propertyBag->Release(); - } - } - - return description; -#else - return name.section(QLatin1Char('\\'), -1); -#endif -} - -QString DirectShowAudioEndpointControl::defaultOutput() const -{ - return m_defaultEndpoint; -} - -QString DirectShowAudioEndpointControl::activeOutput() const -{ - return m_activeEndpoint; -} - -void DirectShowAudioEndpointControl::setActiveOutput(const QString &name) -{ - if (m_activeEndpoint == name) - return; - - if (IMoniker *moniker = m_devices.value(name, 0)) { - IBaseFilter *filter = nullptr; - - if (moniker->BindToObject( - m_bindContext, - nullptr, - IID_IBaseFilter, - reinterpret_cast<void **>(&filter)) == S_OK) { - m_service->setAudioOutput(filter); - - filter->Release(); - } - } -} - -void DirectShowAudioEndpointControl::updateEndpoints() -{ - IMalloc *oleMalloc = nullptr; - if (m_deviceEnumerator && CoGetMalloc(1, &oleMalloc) == S_OK) { - IEnumMoniker *monikers = nullptr; - - if (m_deviceEnumerator->CreateClassEnumerator( - CLSID_AudioRendererCategory, &monikers, 0) == S_OK) { - for (IMoniker *moniker = nullptr; monikers->Next(1, &moniker, nullptr) == S_OK; moniker->Release()) { - OLECHAR *string = nullptr; - if (moniker->GetDisplayName(m_bindContext, nullptr, &string) == S_OK) { - QString deviceId = QString::fromWCharArray(string); - oleMalloc->Free(string); - - moniker->AddRef(); - m_devices.insert(deviceId, moniker); - - if (m_defaultEndpoint.isEmpty() - || deviceId.endsWith(QLatin1String("Default DirectSound Device"))) { - m_defaultEndpoint = deviceId; - } - } - } - monikers->Release(); - } - oleMalloc->Release(); - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/player/directshowaudioendpointcontrol.h b/src/plugins/directshow/player/directshowaudioendpointcontrol.h deleted file mode 100644 index 05c4eb990..000000000 --- a/src/plugins/directshow/player/directshowaudioendpointcontrol.h +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWAUDIOENDPOINTCONTROL_H -#define DIRECTSHOWAUDIOENDPOINTCONTROL_H - -#include "qaudiooutputselectorcontrol.h" - -#include <dshow.h> - -QT_BEGIN_NAMESPACE - -class DirectShowPlayerService; - -class DirectShowAudioEndpointControl : public QAudioOutputSelectorControl -{ - Q_OBJECT -public: - DirectShowAudioEndpointControl(DirectShowPlayerService *service, QObject *parent = nullptr); - ~DirectShowAudioEndpointControl() override; - - QList<QString> availableOutputs() const override; - - QString outputDescription(const QString &name) const override; - - QString defaultOutput() const override; - QString activeOutput() const override; - - void setActiveOutput(const QString& name) override; - -private: - void updateEndpoints(); - - DirectShowPlayerService *m_service; - IBindCtx *m_bindContext = nullptr; - ICreateDevEnum *m_deviceEnumerator = nullptr; - - QMap<QString, IMoniker *> m_devices; - QString m_defaultEndpoint; - QString m_activeEndpoint; -}; - -QT_END_NAMESPACE - -#endif - diff --git a/src/plugins/directshow/player/directshowevrvideowindowcontrol.cpp b/src/plugins/directshow/player/directshowevrvideowindowcontrol.cpp deleted file mode 100644 index 89bfc1467..000000000 --- a/src/plugins/directshow/player/directshowevrvideowindowcontrol.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowevrvideowindowcontrol.h" - -#include "directshowglobal.h" - -DirectShowEvrVideoWindowControl::DirectShowEvrVideoWindowControl(QObject *parent) - : EvrVideoWindowControl(parent) -{ -} - -DirectShowEvrVideoWindowControl::~DirectShowEvrVideoWindowControl() -{ - if (m_evrFilter) - m_evrFilter->Release(); -} - -IBaseFilter *DirectShowEvrVideoWindowControl::filter() -{ - if (!m_evrFilter) { - m_evrFilter = com_new<IBaseFilter>(clsid_EnhancedVideoRenderer); - if (!setEvr(m_evrFilter)) { - m_evrFilter->Release(); - m_evrFilter = nullptr; - } - } - - return m_evrFilter; -} diff --git a/src/plugins/directshow/player/directshowevrvideowindowcontrol.h b/src/plugins/directshow/player/directshowevrvideowindowcontrol.h deleted file mode 100644 index edbde78d6..000000000 --- a/src/plugins/directshow/player/directshowevrvideowindowcontrol.h +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWEVRVIDEOWINDOWCONTROL_H -#define DIRECTSHOWEVRVIDEOWINDOWCONTROL_H - -#include "evrvideowindowcontrol.h" - -struct IBaseFilter; - -QT_BEGIN_NAMESPACE - -class DirectShowEvrVideoWindowControl : public EvrVideoWindowControl -{ -public: - DirectShowEvrVideoWindowControl(QObject *parent = nullptr); - ~DirectShowEvrVideoWindowControl(); - - IBaseFilter *filter(); - -private: - IBaseFilter *m_evrFilter = nullptr; -}; - -QT_END_NAMESPACE - -#endif // DIRECTSHOWEVRVIDEOWINDOWCONTROL_H diff --git a/src/plugins/directshow/player/directshowioreader.cpp b/src/plugins/directshow/player/directshowioreader.cpp deleted file mode 100644 index 3318d57b5..000000000 --- a/src/plugins/directshow/player/directshowioreader.cpp +++ /dev/null @@ -1,462 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowioreader.h" - -#include "directshoweventloop.h" -#include "directshowglobal.h" -#include "directshowiosource.h" - -#include <QtCore/qcoreapplication.h> -#include <QtCore/qcoreevent.h> -#include <QtCore/qiodevice.h> -#include <QtCore/qthread.h> - -QT_BEGIN_NAMESPACE - -class DirectShowSampleRequest -{ -public: - DirectShowSampleRequest( - IMediaSample *sample, DWORD_PTR userData, LONGLONG position, LONG length, BYTE *buffer) - : sample(sample) - , userData(userData) - , position(position) - , length(length) - , buffer(buffer) - { - } - - DirectShowSampleRequest *remove() { DirectShowSampleRequest *n = next; delete this; return n; } - - DirectShowSampleRequest *next = nullptr; - IMediaSample *sample; - DWORD_PTR userData; - LONGLONG position; - LONG length; - BYTE *buffer; - HRESULT result = S_FALSE; -}; - -DirectShowIOReader::DirectShowIOReader( - QIODevice *device, DirectShowIOSource *source, DirectShowEventLoop *loop) - : m_source(source) - , m_device(device) - , m_loop(loop) -{ - moveToThread(device->thread()); - - connect(device, &QIODevice::readyRead, this, &DirectShowIOReader::readyRead); -} - -DirectShowIOReader::~DirectShowIOReader() -{ - flushRequests(); -} - -HRESULT DirectShowIOReader::QueryInterface(REFIID riid, void **ppvObject) -{ - return m_source->QueryInterface(riid, ppvObject); -} - -ULONG DirectShowIOReader::AddRef() -{ - return m_source->AddRef(); -} - -ULONG DirectShowIOReader::Release() -{ - return m_source->Release(); -} - -// IAsyncReader -HRESULT DirectShowIOReader::RequestAllocator( - IMemAllocator *pPreferred, ALLOCATOR_PROPERTIES *pProps, IMemAllocator **ppActual) -{ - if (!ppActual || !pProps) - return E_POINTER; - - ALLOCATOR_PROPERTIES actualProperties; - - if (pProps->cbAlign == 0) - pProps->cbAlign = 1; - - if (pPreferred && pPreferred->SetProperties(pProps, &actualProperties) == S_OK) { - pPreferred->AddRef(); - - *ppActual = pPreferred; - m_source->setAllocator(*ppActual); - return S_OK; - } - - *ppActual = com_new<IMemAllocator>(CLSID_MemoryAllocator); - if (*ppActual) { - if ((*ppActual)->SetProperties(pProps, &actualProperties) == S_OK) { - m_source->setAllocator(*ppActual); - return S_OK; - } - (*ppActual)->Release(); - } - ppActual = nullptr; - return E_FAIL; -} - -HRESULT DirectShowIOReader::Request(IMediaSample *pSample, DWORD_PTR dwUser) -{ - QMutexLocker locker(&m_mutex); - - if (!pSample) - return E_POINTER; - if (m_flushing) - return VFW_E_WRONG_STATE; - - REFERENCE_TIME startTime = 0; - REFERENCE_TIME endTime = 0; - BYTE *buffer; - - if (pSample->GetTime(&startTime, &endTime) != S_OK - || pSample->GetPointer(&buffer) != S_OK) { - return VFW_E_SAMPLE_TIME_NOT_SET; - } - LONGLONG position = startTime / 10000000; - LONG length = qMin<qint64>((endTime - startTime) / 10000000, m_availableLength); - - auto request = new DirectShowSampleRequest(pSample, dwUser, position, length, buffer); - - if (m_pendingTail) { - m_pendingTail->next = request; - } else { - m_pendingHead = request; - m_loop->postEvent(this, new QEvent(QEvent::User)); - } - m_pendingTail = request; - - return S_OK; -} - -HRESULT DirectShowIOReader::WaitForNext( - DWORD dwTimeout, IMediaSample **ppSample, DWORD_PTR *pdwUser) -{ - if (!ppSample || !pdwUser) - return E_POINTER; - - QMutexLocker locker(&m_mutex); - - do { - if (m_readyHead) { - DirectShowSampleRequest *request = m_readyHead; - - *ppSample = request->sample; - *pdwUser = request->userData; - - HRESULT hr = request->result; - - m_readyHead = request->next; - - if (!m_readyHead) - m_readyTail = nullptr; - - delete request; - - return hr; - } - if (m_flushing) { - *ppSample = nullptr; - *pdwUser = 0; - - return VFW_E_WRONG_STATE; - } - } while (m_wait.wait(&m_mutex, dwTimeout)); - - *ppSample = nullptr; - *pdwUser = 0; - - return VFW_E_TIMEOUT; -} - -HRESULT DirectShowIOReader::SyncReadAligned(IMediaSample *pSample) -{ - if (!pSample) - return E_POINTER; - - REFERENCE_TIME startTime = 0; - REFERENCE_TIME endTime = 0; - BYTE *buffer; - - if (pSample->GetTime(&startTime, &endTime) != S_OK - || pSample->GetPointer(&buffer) != S_OK) { - return VFW_E_SAMPLE_TIME_NOT_SET; - } - LONGLONG position = startTime / 10000000; - LONG length = (endTime - startTime) / 10000000; - - QMutexLocker locker(&m_mutex); - - if (thread() == QThread::currentThread()) { - qint64 bytesRead = 0; - - HRESULT hr = blockingRead(position, length, buffer, &bytesRead); - if (SUCCEEDED(hr)) - pSample->SetActualDataLength(bytesRead); - - return hr; - } - m_synchronousPosition = position; - m_synchronousLength = length; - m_synchronousBuffer = buffer; - - m_loop->postEvent(this, new QEvent(QEvent::User)); - - m_wait.wait(&m_mutex); - - m_synchronousBuffer = nullptr; - - if (SUCCEEDED(m_synchronousResult)) - pSample->SetActualDataLength(m_synchronousBytesRead); - - return m_synchronousResult; -} - -HRESULT DirectShowIOReader::SyncRead(LONGLONG llPosition, LONG lLength, BYTE *pBuffer) -{ - if (!pBuffer) - return E_POINTER; - - if (thread() == QThread::currentThread()) { - qint64 bytesRead; - return blockingRead(llPosition, lLength, pBuffer, &bytesRead); - } - QMutexLocker locker(&m_mutex); - - m_synchronousPosition = llPosition; - m_synchronousLength = lLength; - m_synchronousBuffer = pBuffer; - - m_loop->postEvent(this, new QEvent(QEvent::User)); - - m_wait.wait(&m_mutex); - - m_synchronousBuffer = nullptr; - - return m_synchronousResult; -} - -HRESULT DirectShowIOReader::Length(LONGLONG *pTotal, LONGLONG *pAvailable) -{ - if (!pTotal || !pAvailable) - return E_POINTER; - - QMutexLocker locker(&m_mutex); - *pTotal = m_totalLength; - *pAvailable = m_availableLength; - return S_OK; -} - - -HRESULT DirectShowIOReader::BeginFlush() -{ - QMutexLocker locker(&m_mutex); - - if (m_flushing) - return S_FALSE; - - m_flushing = true; - - flushRequests(); - - m_wait.wakeAll(); - - return S_OK; -} - -HRESULT DirectShowIOReader::EndFlush() -{ - QMutexLocker locker(&m_mutex); - - if (!m_flushing) - return S_FALSE; - - m_flushing = false; - - return S_OK; -} - -void DirectShowIOReader::customEvent(QEvent *event) -{ - if (event->type() == QEvent::User) { - readyRead(); - } else { - QObject::customEvent(event); - } -} - -void DirectShowIOReader::readyRead() -{ - QMutexLocker locker(&m_mutex); - - m_availableLength = m_device->bytesAvailable() + m_device->pos(); - m_totalLength = m_device->size(); - - if (m_synchronousBuffer) { - if (nonBlockingRead( - m_synchronousPosition, - m_synchronousLength, - m_synchronousBuffer, - &m_synchronousBytesRead, - &m_synchronousResult)) { - m_wait.wakeAll(); - } - } else { - qint64 bytesRead = 0; - - while (m_pendingHead && nonBlockingRead( - m_pendingHead->position, - m_pendingHead->length, - m_pendingHead->buffer, - &bytesRead, - &m_pendingHead->result)) { - m_pendingHead->sample->SetActualDataLength(bytesRead); - - if (m_readyTail) - m_readyTail->next = m_pendingHead; - m_readyTail = m_pendingHead; - - m_pendingHead = m_pendingHead->next; - - m_readyTail->next = nullptr; - - if (!m_pendingHead) - m_pendingTail = nullptr; - - if (!m_readyHead) - m_readyHead = m_readyTail; - - m_wait.wakeAll(); - } - } -} - -HRESULT DirectShowIOReader::blockingRead( - LONGLONG position, LONG length, BYTE *buffer, qint64 *bytesRead) -{ - *bytesRead = 0; - - if (qint64(position) > m_device->size()) - return S_FALSE; - - const qint64 maxSize = qMin<qint64>(m_device->size(), position + length); - - while (m_device->bytesAvailable() + m_device->pos() < maxSize) { - if (!m_device->waitForReadyRead(-1)) - return S_FALSE; - } - - if (m_device->pos() != position && !m_device->seek(position)) - return S_FALSE; - - const qint64 maxBytes = qMin<qint64>(length, m_device->bytesAvailable()); - - *bytesRead = m_device->read(reinterpret_cast<char *>(buffer), maxBytes); - - if (*bytesRead != length) { - ::memset(buffer + *bytesRead, 0, length - *bytesRead); - - return S_FALSE; - } - return S_OK; -} - -bool DirectShowIOReader::nonBlockingRead( - LONGLONG position, LONG length, BYTE *buffer, qint64 *bytesRead, HRESULT *result) -{ - const qint64 maxSize = qMin<qint64>(m_device->size(), position + length); - - if (position > m_device->size()) { - *bytesRead = 0; - *result = S_FALSE; - - return true; - } - if (m_device->bytesAvailable() + m_device->pos() >= maxSize) { - if (m_device->pos() != position && !m_device->seek(position)) { - *bytesRead = 0; - *result = S_FALSE; - - return true; - } - const qint64 maxBytes = qMin<qint64>(length, m_device->bytesAvailable()); - - *bytesRead = m_device->read(reinterpret_cast<char *>(buffer), maxBytes); - - if (*bytesRead != length) { - ::memset(buffer + *bytesRead, 0, length - *bytesRead); - - *result = S_FALSE; - } else { - *result = S_OK; - } - - return true; - } - return false; -} - -void DirectShowIOReader::flushRequests() -{ - while (m_pendingHead) { - m_pendingHead->result = VFW_E_WRONG_STATE; - - if (m_readyTail) - m_readyTail->next = m_pendingHead; - - m_readyTail = m_pendingHead; - - m_pendingHead = m_pendingHead->next; - - m_readyTail->next = nullptr; - - if (!m_pendingHead) - m_pendingTail = nullptr; - - if (!m_readyHead) - m_readyHead = m_readyTail; - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/player/directshowioreader.h b/src/plugins/directshow/player/directshowioreader.h deleted file mode 100644 index a0f2d7adb..000000000 --- a/src/plugins/directshow/player/directshowioreader.h +++ /dev/null @@ -1,120 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWIOREADER_H -#define DIRECTSHOWIOREADER_H - -#include <dshow.h> - -#include <QtCore/qmutex.h> -#include <QtCore/qobject.h> -#include <QtCore/qwaitcondition.h> - -QT_BEGIN_NAMESPACE -class QIODevice; - -class DirectShowEventLoop; -class DirectShowIOSource; -class DirectShowSampleRequest; - -class DirectShowIOReader : public QObject, public IAsyncReader -{ - Q_OBJECT -public: - DirectShowIOReader(QIODevice *device, DirectShowIOSource *source, DirectShowEventLoop *loop); - ~DirectShowIOReader() override; - - // IUnknown - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) override; - ULONG STDMETHODCALLTYPE AddRef() override; - ULONG STDMETHODCALLTYPE Release() override; - - // IAsyncReader - HRESULT STDMETHODCALLTYPE RequestAllocator( - IMemAllocator *pPreferred, ALLOCATOR_PROPERTIES *pProps, - IMemAllocator **ppActual) override; - - HRESULT STDMETHODCALLTYPE Request(IMediaSample *pSample, DWORD_PTR dwUser) override; - - HRESULT STDMETHODCALLTYPE WaitForNext( - DWORD dwTimeout, IMediaSample **ppSample, DWORD_PTR *pdwUser) override; - - HRESULT STDMETHODCALLTYPE SyncReadAligned(IMediaSample *pSample) override; - - HRESULT STDMETHODCALLTYPE SyncRead(LONGLONG llPosition, LONG lLength, BYTE *pBuffer) override; - - HRESULT STDMETHODCALLTYPE Length(LONGLONG *pTotal, LONGLONG *pAvailable) override; - - HRESULT STDMETHODCALLTYPE BeginFlush() override; - HRESULT STDMETHODCALLTYPE EndFlush() override; - -protected: - void customEvent(QEvent *event) override; - -private Q_SLOTS: - void readyRead(); - -private: - HRESULT blockingRead(LONGLONG position, LONG length, BYTE *buffer, qint64 *bytesRead); - bool nonBlockingRead( - LONGLONG position, LONG length, BYTE *buffer, qint64 *bytesRead, HRESULT *result); - void flushRequests(); - - DirectShowIOSource *m_source; - QIODevice *m_device; - DirectShowEventLoop *m_loop; - DirectShowSampleRequest *m_pendingHead = nullptr; - DirectShowSampleRequest *m_pendingTail = nullptr; - DirectShowSampleRequest *m_readyHead = nullptr; - DirectShowSampleRequest *m_readyTail = nullptr; - LONGLONG m_synchronousPosition = 0; - LONG m_synchronousLength = 0; - qint64 m_synchronousBytesRead = 0; - BYTE *m_synchronousBuffer = nullptr; - HRESULT m_synchronousResult = S_OK; - LONGLONG m_totalLength = 0; - LONGLONG m_availableLength = 0; - bool m_flushing = false; - QMutex m_mutex; - QWaitCondition m_wait; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/directshow/player/directshowiosource.cpp b/src/plugins/directshow/player/directshowiosource.cpp deleted file mode 100644 index 54c043c17..000000000 --- a/src/plugins/directshow/player/directshowiosource.cpp +++ /dev/null @@ -1,530 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowiosource.h" - -#include "directshowglobal.h" -#include "directshowmediatype.h" -#include "directshowmediatypeenum.h" -#include "directshowpinenum.h" - -#include <QtCore/qcoreapplication.h> -#include <QtCore/qurl.h> - -QT_BEGIN_NAMESPACE - -static const GUID directshow_subtypes[] = -{ - MEDIASUBTYPE_NULL, - MEDIASUBTYPE_Avi, - MEDIASUBTYPE_Asf, - MEDIASUBTYPE_MPEG1Video, - MEDIASUBTYPE_QTMovie, - MEDIASUBTYPE_WAVE, - MEDIASUBTYPE_AIFF, - MEDIASUBTYPE_AU, - MEDIASUBTYPE_DssVideo, - MEDIASUBTYPE_MPEG1Audio, - MEDIASUBTYPE_MPEG1System, - MEDIASUBTYPE_MPEG1VideoCD -}; - -DirectShowIOSource::DirectShowIOSource(DirectShowEventLoop *loop) - : m_loop(loop) -{ - // This filter has only one possible output type, that is, a stream of data - // with no particular subtype. The graph builder will try every demux/decode filters - // to find one able to decode the stream. - // - // The filter works in pull mode, the downstream filter is responsible for requesting - // samples from this one. - // - AM_MEDIA_TYPE type - { - MEDIATYPE_Stream, // majortype - MEDIASUBTYPE_NULL, // subtype - TRUE, // bFixedSizeSamples - FALSE, // bTemporalCompression - 1, // lSampleSize - GUID_NULL, // formattype - nullptr, // pUnk - 0, // cbFormat - nullptr, // pbFormat - }; - - for (const auto &directshowSubtype : directshow_subtypes) { - type.subtype = directshowSubtype; - m_supportedMediaTypes.append(DirectShowMediaType(type)); - } -} - -DirectShowIOSource::~DirectShowIOSource() -{ - Q_ASSERT(m_ref == 0); - - delete m_reader; -} - -void DirectShowIOSource::setDevice(QIODevice *device) -{ - Q_ASSERT(!m_reader); - - m_reader = new DirectShowIOReader(device, this, m_loop); -} - -void DirectShowIOSource::setAllocator(IMemAllocator *allocator) -{ - if (m_allocator == allocator) - return; - - if (m_allocator) - m_allocator->Release(); - - m_allocator = allocator; - - if (m_allocator) - m_allocator->AddRef(); -} - -// IUnknown -HRESULT DirectShowIOSource::QueryInterface(REFIID riid, void **ppvObject) -{ - // 2dd74950-a890-11d1-abe8-00a0c905f375 - static const GUID iid_IAmFilterMiscFlags = { - 0x2dd74950, 0xa890, 0x11d1, {0xab, 0xe8, 0x00, 0xa0, 0xc9, 0x05, 0xf3, 0x75}}; - - if (!ppvObject) - return E_POINTER; - - if (riid == IID_IUnknown || riid == IID_IPersist || riid == IID_IMediaFilter - || riid == IID_IBaseFilter) { - *ppvObject = static_cast<IBaseFilter *>(this); - } else if (riid == iid_IAmFilterMiscFlags) { - *ppvObject = static_cast<IAMFilterMiscFlags *>(this); - } else if (riid == IID_IPin) { - *ppvObject = static_cast<IPin *>(this); - } else if (riid == IID_IAsyncReader) { - m_queriedForAsyncReader = true; - *ppvObject = static_cast<IAsyncReader *>(m_reader); - } else { - *ppvObject = nullptr; - - return E_NOINTERFACE; - } - - AddRef(); - - return S_OK; -} - -ULONG DirectShowIOSource::AddRef() -{ - return InterlockedIncrement(&m_ref); -} - -ULONG DirectShowIOSource::Release() -{ - ULONG ref = InterlockedDecrement(&m_ref); - - if (ref == 0) { - delete this; - } - - return ref; -} - -// IPersist -HRESULT DirectShowIOSource::GetClassID(CLSID *pClassID) -{ - *pClassID = CLSID_NULL; - - return S_OK; -} - -// IMediaFilter -HRESULT DirectShowIOSource::Run(REFERENCE_TIME tStart) -{ - Q_UNUSED(tStart); - QMutexLocker locker(&m_mutex); - - m_state = State_Running; - - return S_OK; -} - -HRESULT DirectShowIOSource::Pause() -{ - QMutexLocker locker(&m_mutex); - - m_state = State_Paused; - - return S_OK; -} - -HRESULT DirectShowIOSource::Stop() -{ - QMutexLocker locker(&m_mutex); - - m_state = State_Stopped; - - return S_OK; -} - -HRESULT DirectShowIOSource::GetState(DWORD dwMilliSecsTimeout, FILTER_STATE *pState) -{ - Q_UNUSED(dwMilliSecsTimeout); - - if (!pState) - return E_POINTER; - - QMutexLocker locker(&m_mutex); - *pState = m_state; - return S_OK; -} - -HRESULT DirectShowIOSource::SetSyncSource(IReferenceClock *pClock) -{ - QMutexLocker locker(&m_mutex); - - if (m_clock) - m_clock->Release(); - - m_clock = pClock; - - if (m_clock) - m_clock->AddRef(); - - return S_OK; -} - -HRESULT DirectShowIOSource::GetSyncSource(IReferenceClock **ppClock) -{ - if (!ppClock) - return E_POINTER; - - if (!m_clock) { - *ppClock = nullptr; - return S_FALSE; - } - m_clock->AddRef(); - *ppClock = m_clock; - return S_OK; -} - -// IBaseFilter -HRESULT DirectShowIOSource::EnumPins(IEnumPins **ppEnum) -{ - if (!ppEnum) - return E_POINTER; - - *ppEnum = new DirectShowPinEnum(QList<IPin *>() << this); - return S_OK; -} - -HRESULT DirectShowIOSource::FindPin(LPCWSTR Id, IPin **ppPin) -{ - if (!ppPin || !Id) - return E_POINTER; - - QMutexLocker locker(&m_mutex); - if (m_pinId == QStringView(Id)) { - AddRef(); - *ppPin = this; - return S_OK; - } - *ppPin = nullptr; - return VFW_E_NOT_FOUND; -} - -HRESULT DirectShowIOSource::JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName) -{ - QMutexLocker locker(&m_mutex); - - m_graph = pGraph; - m_filterName = QString::fromWCharArray(pName); - - return S_OK; -} - -HRESULT DirectShowIOSource::QueryFilterInfo(FILTER_INFO *pInfo) -{ - if (!pInfo) - return E_POINTER; - - QString name = m_filterName; - if (name.length() >= MAX_FILTER_NAME) - name.truncate(MAX_FILTER_NAME - 1); - - int length = name.toWCharArray(pInfo->achName); - pInfo->achName[length] = '\0'; - - if (m_graph) - m_graph->AddRef(); - - pInfo->pGraph = m_graph; - - return S_OK; -} - -HRESULT DirectShowIOSource::QueryVendorInfo(LPWSTR *pVendorInfo) -{ - Q_UNUSED(pVendorInfo); - - return E_NOTIMPL; -} - -// IAMFilterMiscFlags -ULONG DirectShowIOSource::GetMiscFlags() -{ - return AM_FILTER_MISC_FLAGS_IS_SOURCE; -} - -// IPin -HRESULT DirectShowIOSource::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) -{ - if (!pReceivePin) - return E_POINTER; - - QMutexLocker locker(&m_mutex); - - if (m_state != State_Stopped) - return VFW_E_NOT_STOPPED; - - if (m_peerPin) - return VFW_E_ALREADY_CONNECTED; - - // If we get a type from the graph manager, check that we support that - if (pmt && pmt->majortype != MEDIATYPE_Stream) - return VFW_E_TYPE_NOT_ACCEPTED; - - // This filter only works in pull mode, the downstream filter must query for the - // AsyncReader interface during ReceiveConnection(). - // If it doesn't, we can't connect to it. - m_queriedForAsyncReader = false; - HRESULT hr = 0; - // Negotiation of media type - // - Complete'ish type (Stream with subtype specified). - if (pmt && pmt->subtype != MEDIASUBTYPE_NULL /* aka. GUID_NULL */) { - hr = pReceivePin->ReceiveConnection(this, pmt); - // Update the media type for the current connection. - if (SUCCEEDED(hr)) - DirectShowMediaType::copy(&m_connectionMediaType, pmt); - } else if (pmt && pmt->subtype == MEDIATYPE_NULL) { // - Partial type (Stream, but no subtype specified). - DirectShowMediaType::copy(&m_connectionMediaType, pmt); - // Check if the receiving pin accepts any of the streaming subtypes. - for (const DirectShowMediaType &t : qAsConst(m_supportedMediaTypes)) { - m_connectionMediaType->subtype = t->subtype; - hr = pReceivePin->ReceiveConnection(this, &m_connectionMediaType); - if (SUCCEEDED(hr)) - break; - } - } else { // - No media type specified. - // Check if the receiving pin accepts any of the streaming types. - for (const DirectShowMediaType &t : qAsConst(m_supportedMediaTypes)) { - hr = pReceivePin->ReceiveConnection(this, &t); - if (SUCCEEDED(hr)) { - m_connectionMediaType = t; - break; - } - } - } - - if (SUCCEEDED(hr) && m_queriedForAsyncReader) { - m_peerPin = pReceivePin; - m_peerPin->AddRef(); - } else { - pReceivePin->Disconnect(); - if (m_allocator) { - m_allocator->Release(); - m_allocator = nullptr; - } - if (!m_queriedForAsyncReader) - hr = VFW_E_NO_TRANSPORT; - - m_connectionMediaType.clear(); - } - - return hr; -} - -HRESULT DirectShowIOSource::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt) -{ - Q_UNUSED(pConnector); - Q_UNUSED(pmt); - // Output pin. - return E_NOTIMPL; -} - -HRESULT DirectShowIOSource::Disconnect() -{ - QMutexLocker locker(&m_mutex); - - if (!m_peerPin) - return S_FALSE; - if (m_state != State_Stopped) - return VFW_E_NOT_STOPPED; - - HRESULT hr = m_peerPin->Disconnect(); - if (!SUCCEEDED(hr)) - return hr; - - if (m_allocator) { - m_allocator->Release(); - m_allocator = nullptr; - } - - m_peerPin->Release(); - m_peerPin = nullptr; - - return S_OK; -} - -HRESULT DirectShowIOSource::ConnectedTo(IPin **ppPin) -{ - if (!ppPin) - return E_POINTER; - - QMutexLocker locker(&m_mutex); - if (!m_peerPin) { - *ppPin = nullptr; - return VFW_E_NOT_CONNECTED; - } - m_peerPin->AddRef(); - *ppPin = m_peerPin; - return S_OK; -} - -HRESULT DirectShowIOSource::ConnectionMediaType(AM_MEDIA_TYPE *pmt) -{ - if (!pmt) - return E_POINTER; - - QMutexLocker locker(&m_mutex); - if (!m_peerPin) { - pmt = nullptr; - return VFW_E_NOT_CONNECTED; - } - DirectShowMediaType::copy(pmt, &m_connectionMediaType); - return S_OK; -} - -HRESULT DirectShowIOSource::QueryPinInfo(PIN_INFO *pInfo) -{ - if (!pInfo) - return E_POINTER; - - AddRef(); - - pInfo->pFilter = this; - pInfo->dir = PINDIR_OUTPUT; - - const int bytes = qMin(MAX_FILTER_NAME, (m_pinId.length() + 1) * 2); - - ::memcpy(pInfo->achName, m_pinId.utf16(), bytes); - - return S_OK; -} - -HRESULT DirectShowIOSource::QueryId(LPWSTR *Id) -{ - if (!Id) - return E_POINTER; - - const int bytes = (m_pinId.length() + 1) * 2; - *Id = static_cast<LPWSTR>(::CoTaskMemAlloc(bytes)); - ::memcpy(*Id, m_pinId.utf16(), bytes); - return S_OK; -} - -HRESULT DirectShowIOSource::QueryAccept(const AM_MEDIA_TYPE *pmt) -{ - if (!pmt) - return E_POINTER; - return pmt->majortype == MEDIATYPE_Stream ? S_OK : S_FALSE; -} - -HRESULT DirectShowIOSource::EnumMediaTypes(IEnumMediaTypes **ppEnum) -{ - if (!ppEnum) - return E_POINTER; - *ppEnum = new DirectShowMediaTypeEnum(m_supportedMediaTypes); - return S_OK; -} - -HRESULT DirectShowIOSource::QueryInternalConnections(IPin **apPin, ULONG *nPin) -{ - Q_UNUSED(apPin); - Q_UNUSED(nPin); - - return E_NOTIMPL; -} - -HRESULT DirectShowIOSource::EndOfStream() -{ - return S_OK; -} - -HRESULT DirectShowIOSource::BeginFlush() -{ - return m_reader->BeginFlush(); -} - -HRESULT DirectShowIOSource::EndFlush() -{ - return m_reader->EndFlush(); -} - -HRESULT DirectShowIOSource::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) -{ - Q_UNUSED(tStart); - Q_UNUSED(tStop); - Q_UNUSED(dRate); - - return S_OK; -} - -HRESULT DirectShowIOSource::QueryDirection(PIN_DIRECTION *pPinDir) -{ - if (!pPinDir) - return E_POINTER; - *pPinDir = PINDIR_OUTPUT; - return S_OK; -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/player/directshowiosource.h b/src/plugins/directshow/player/directshowiosource.h deleted file mode 100644 index 837842518..000000000 --- a/src/plugins/directshow/player/directshowiosource.h +++ /dev/null @@ -1,140 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWIOSOURCE_H -#define DIRECTSHOWIOSOURCE_H - -#include "directshowglobal.h" -#include "directshowioreader.h" -#include "directshowmediatype.h" - -#include <QtCore/qfile.h> - -QT_BEGIN_NAMESPACE - -class DirectShowIOSource - : public IBaseFilter - , public IAMFilterMiscFlags - , public IPin -{ - Q_DISABLE_COPY(DirectShowIOSource) -public: - DirectShowIOSource(DirectShowEventLoop *loop); - virtual ~DirectShowIOSource(); - - void setDevice(QIODevice *device); - void setAllocator(IMemAllocator *allocator); - - // IUnknown - HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObject) override; - ULONG STDMETHODCALLTYPE AddRef() override; - ULONG STDMETHODCALLTYPE Release() override; - - // IPersist - HRESULT STDMETHODCALLTYPE GetClassID(CLSID *pClassID) override; - - // IMediaFilter - HRESULT STDMETHODCALLTYPE Run(REFERENCE_TIME tStart) override; - HRESULT STDMETHODCALLTYPE Pause() override; - HRESULT STDMETHODCALLTYPE Stop() override; - - HRESULT STDMETHODCALLTYPE GetState(DWORD dwMilliSecsTimeout, FILTER_STATE *pState) override; - - HRESULT STDMETHODCALLTYPE SetSyncSource(IReferenceClock *pClock) override; - HRESULT STDMETHODCALLTYPE GetSyncSource(IReferenceClock **ppClock) override; - - // IBaseFilter - HRESULT STDMETHODCALLTYPE EnumPins(IEnumPins **ppEnum) override; - HRESULT STDMETHODCALLTYPE FindPin(LPCWSTR Id, IPin **ppPin) override; - - HRESULT STDMETHODCALLTYPE JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName) override; - - HRESULT STDMETHODCALLTYPE QueryFilterInfo(FILTER_INFO *pInfo) override; - HRESULT STDMETHODCALLTYPE QueryVendorInfo(LPWSTR *pVendorInfo) override; - - // IAMFilterMiscFlags - ULONG STDMETHODCALLTYPE GetMiscFlags() override; - - // IPin - HRESULT STDMETHODCALLTYPE Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) override; - HRESULT STDMETHODCALLTYPE ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt) override; - HRESULT STDMETHODCALLTYPE Disconnect() override; - HRESULT STDMETHODCALLTYPE ConnectedTo(IPin **ppPin) override; - - HRESULT STDMETHODCALLTYPE ConnectionMediaType(AM_MEDIA_TYPE *pmt) override; - - HRESULT STDMETHODCALLTYPE QueryPinInfo(PIN_INFO *pInfo) override; - HRESULT STDMETHODCALLTYPE QueryId(LPWSTR *Id) override; - - HRESULT STDMETHODCALLTYPE QueryAccept(const AM_MEDIA_TYPE *pmt) override; - - HRESULT STDMETHODCALLTYPE EnumMediaTypes(IEnumMediaTypes **ppEnum) override; - - HRESULT STDMETHODCALLTYPE QueryInternalConnections(IPin **apPin, ULONG *nPin) override; - - HRESULT STDMETHODCALLTYPE EndOfStream() override; - - HRESULT STDMETHODCALLTYPE BeginFlush() override; - HRESULT STDMETHODCALLTYPE EndFlush() override; - - HRESULT STDMETHODCALLTYPE NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, - double dRate) override; - - HRESULT STDMETHODCALLTYPE QueryDirection(PIN_DIRECTION *pPinDir) override; - -private: - volatile LONG m_ref = 1; - FILTER_STATE m_state = State_Stopped; - DirectShowIOReader *m_reader = nullptr; - DirectShowEventLoop *m_loop; - IFilterGraph *m_graph = nullptr; - IReferenceClock *m_clock = nullptr; - IMemAllocator *m_allocator = nullptr; - IPin *m_peerPin = nullptr; - DirectShowMediaType m_connectionMediaType; - QList<DirectShowMediaType> m_supportedMediaTypes; - QString m_filterName; - const QString m_pinId = QLatin1String("Data"); - bool m_queriedForAsyncReader = false; - QMutex m_mutex; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/directshow/player/directshowmetadatacontrol.cpp b/src/plugins/directshow/player/directshowmetadatacontrol.cpp deleted file mode 100644 index 61138951c..000000000 --- a/src/plugins/directshow/player/directshowmetadatacontrol.cpp +++ /dev/null @@ -1,697 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <dshow.h> -#ifdef min -#undef min -#endif -#ifdef max -#undef max -#endif - -#include <QtMultimedia/qmediametadata.h> -#include <QtCore/qcoreapplication.h> -#include <QSize> -#include <qdatetime.h> -#include <qimage.h> - -#include <initguid.h> -#include <qnetwork.h> - -#include "directshowmetadatacontrol.h" -#include "directshowplayerservice.h" - -#include <QtMultimedia/private/qtmultimedia-config_p.h> - -#if QT_CONFIG(wmsdk) -#include <wmsdk.h> -#endif - -#if QT_CONFIG(wshellitem) -#include <shlobj.h> -#include <propkeydef.h> -#include <private/qsystemlibrary_p.h> - -DEFINE_PROPERTYKEY(PKEY_Author, 0xF29F85E0, 0x4FF9, 0x1068, 0xAB, 0x91, 0x08, 0x00, 0x2B, 0x27, 0xB3, 0xD9, 4); -DEFINE_PROPERTYKEY(PKEY_Title, 0xF29F85E0, 0x4FF9, 0x1068, 0xAB, 0x91, 0x08, 0x00, 0x2B, 0x27, 0xB3, 0xD9, 2); -DEFINE_PROPERTYKEY(PKEY_Media_SubTitle, 0x56A3372E, 0xCE9C, 0x11D2, 0x9F, 0x0E, 0x00, 0x60, 0x97, 0xC6, 0x86, 0xF6, 38); -DEFINE_PROPERTYKEY(PKEY_ParentalRating, 0x64440492, 0x4C8B, 0x11D1, 0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03, 21); -DEFINE_PROPERTYKEY(PKEY_Comment, 0xF29F85E0, 0x4FF9, 0x1068, 0xAB, 0x91, 0x08, 0x00, 0x2B, 0x27, 0xB3, 0xD9, 6); -DEFINE_PROPERTYKEY(PKEY_Copyright, 0x64440492, 0x4C8B, 0x11D1, 0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03, 11); -DEFINE_PROPERTYKEY(PKEY_Media_ProviderStyle, 0x64440492, 0x4C8B, 0x11D1, 0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03, 40); -DEFINE_PROPERTYKEY(PKEY_Media_Year, 0x56A3372E, 0xCE9C, 0x11D2, 0x9F, 0x0E, 0x00, 0x60, 0x97, 0xC6, 0x86, 0xF6, 5); -DEFINE_PROPERTYKEY(PKEY_Media_DateEncoded, 0x2E4B640D, 0x5019, 0x46D8, 0x88, 0x81, 0x55, 0x41, 0x4C, 0xC5, 0xCA, 0xA0, 100); -DEFINE_PROPERTYKEY(PKEY_Rating, 0x64440492, 0x4C8B, 0x11D1, 0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03, 9); -DEFINE_PROPERTYKEY(PKEY_Keywords, 0xF29F85E0, 0x4FF9, 0x1068, 0xAB, 0x91, 0x08, 0x00, 0x2B, 0x27, 0xB3, 0xD9, 5); -DEFINE_PROPERTYKEY(PKEY_Language, 0xD5CDD502, 0x2E9C, 0x101B, 0x93, 0x97, 0x08, 0x00, 0x2B, 0x2C, 0xF9, 0xAE, 28); -DEFINE_PROPERTYKEY(PKEY_Media_Publisher, 0x64440492, 0x4C8B, 0x11D1, 0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03, 30); -DEFINE_PROPERTYKEY(PKEY_Media_Duration, 0x64440490, 0x4C8B, 0x11D1, 0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03, 3); -DEFINE_PROPERTYKEY(PKEY_Audio_EncodingBitrate, 0x64440490, 0x4C8B, 0x11D1, 0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03, 4); -DEFINE_PROPERTYKEY(PKEY_Media_AverageLevel, 0x09EDD5B6, 0xB301, 0x43C5, 0x99, 0x90, 0xD0, 0x03, 0x02, 0xEF, 0xFD, 0x46, 100); -DEFINE_PROPERTYKEY(PKEY_Audio_ChannelCount, 0x64440490, 0x4C8B, 0x11D1, 0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03, 7); -DEFINE_PROPERTYKEY(PKEY_Audio_PeakValue, 0x2579E5D0, 0x1116, 0x4084, 0xBD, 0x9A, 0x9B, 0x4F, 0x7C, 0xB4, 0xDF, 0x5E, 100); -DEFINE_PROPERTYKEY(PKEY_Audio_SampleRate, 0x64440490, 0x4C8B, 0x11D1, 0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03, 5); -DEFINE_PROPERTYKEY(PKEY_Audio_Format, 0x64440490, 0x4C8B, 0x11D1, 0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03, 2); -DEFINE_PROPERTYKEY(PKEY_Music_AlbumTitle, 0x56A3372E, 0xCE9C, 0x11D2, 0x9F, 0x0E, 0x00, 0x60, 0x97, 0xC6, 0x86, 0xF6, 4); -DEFINE_PROPERTYKEY(PKEY_Music_AlbumArtist, 0x56A3372E, 0xCE9C, 0x11D2, 0x9F, 0x0E, 0x00, 0x60, 0x97, 0xC6, 0x86, 0xF6, 13); -DEFINE_PROPERTYKEY(PKEY_Music_Artist, 0x56A3372E, 0xCE9C, 0x11D2, 0x9F, 0x0E, 0x00, 0x60, 0x97, 0xC6, 0x86, 0xF6, 2); -DEFINE_PROPERTYKEY(PKEY_Music_Composer, 0x64440492, 0x4C8B, 0x11D1, 0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03, 19); -DEFINE_PROPERTYKEY(PKEY_Music_Conductor, 0x56A3372E, 0xCE9C, 0x11D2, 0x9F, 0x0E, 0x00, 0x60, 0x97, 0xC6, 0x86, 0xF6, 36); -DEFINE_PROPERTYKEY(PKEY_Music_Lyrics, 0x56A3372E, 0xCE9C, 0x11D2, 0x9F, 0x0E, 0x00, 0x60, 0x97, 0xC6, 0x86, 0xF6, 12); -DEFINE_PROPERTYKEY(PKEY_Music_Mood, 0x56A3372E, 0xCE9C, 0x11D2, 0x9F, 0x0E, 0x00, 0x60, 0x97, 0xC6, 0x86, 0xF6, 39); -DEFINE_PROPERTYKEY(PKEY_Music_TrackNumber, 0x56A3372E, 0xCE9C, 0x11D2, 0x9F, 0x0E, 0x00, 0x60, 0x97, 0xC6, 0x86, 0xF6, 7); -DEFINE_PROPERTYKEY(PKEY_Music_Genre, 0x56A3372E, 0xCE9C, 0x11D2, 0x9F, 0x0E, 0x00, 0x60, 0x97, 0xC6, 0x86, 0xF6, 11); -DEFINE_PROPERTYKEY(PKEY_ThumbnailStream, 0xF29F85E0, 0x4FF9, 0x1068, 0xAB, 0x91, 0x08, 0x00, 0x2B, 0x27, 0xB3, 0xD9, 27); -DEFINE_PROPERTYKEY(PKEY_Video_FrameHeight, 0x64440491, 0x4C8B, 0x11D1, 0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03, 4); -DEFINE_PROPERTYKEY(PKEY_Video_FrameWidth, 0x64440491, 0x4C8B, 0x11D1, 0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03, 3); -DEFINE_PROPERTYKEY(PKEY_Video_HorizontalAspectRatio, 0x64440491, 0x4C8B, 0x11D1, 0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03, 42); -DEFINE_PROPERTYKEY(PKEY_Video_VerticalAspectRatio, 0x64440491, 0x4C8B, 0x11D1, 0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03, 45); -DEFINE_PROPERTYKEY(PKEY_Video_FrameRate, 0x64440491, 0x4C8B, 0x11D1, 0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03, 6); -DEFINE_PROPERTYKEY(PKEY_Video_EncodingBitrate, 0x64440491, 0x4C8B, 0x11D1, 0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03, 8); -DEFINE_PROPERTYKEY(PKEY_Video_Director, 0x64440492, 0x4C8B, 0x11D1, 0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03, 20); -DEFINE_PROPERTYKEY(PKEY_Video_Compression, 0x64440491, 0x4C8B, 0x11D1, 0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03, 10); -DEFINE_PROPERTYKEY(PKEY_Media_Writer, 0x64440492, 0x4C8B, 0x11D1, 0x8B, 0x70, 0x08, 0x00, 0x36, 0xB1, 0x1A, 0x03, 23); - -static QString nameForGUIDString(const QString &guid) -{ - // Audio formats - if (guid == "{00001610-0000-0010-8000-00AA00389B71}" || guid == "{000000FF-0000-0010-8000-00AA00389B71}") - return QStringLiteral("MPEG AAC Audio"); - if (guid == "{00001600-0000-0010-8000-00AA00389B71}") - return QStringLiteral("MPEG ADTS AAC Audio"); - if (guid == "{00000092-0000-0010-8000-00AA00389B71}") - return QStringLiteral("Dolby AC-3 SPDIF"); - if (guid == "{E06D802C-DB46-11CF-B4D1-00805F6CBBEA}" || guid == "{00002000-0000-0010-8000-00AA00389B71}") - return QStringLiteral("Dolby AC-3"); - if (guid == "{A7FB87AF-2D02-42FB-A4D4-05CD93843BDD}") - return QStringLiteral("Dolby Digital Plus"); - if (guid == "{00000009-0000-0010-8000-00AA00389B71}") - return QStringLiteral("DRM"); - if (guid == "{00000008-0000-0010-8000-00AA00389B71}") - return QStringLiteral("Digital Theater Systems Audio (DTS)"); - if (guid == "{00000003-0000-0010-8000-00AA00389B71}") - return QStringLiteral("IEEE Float Audio"); - if (guid == "{00000055-0000-0010-8000-00AA00389B71}") - return QStringLiteral("MPEG Audio Layer-3 (MP3)"); - if (guid == "{00000050-0000-0010-8000-00AA00389B71}") - return QStringLiteral("MPEG-1 Audio"); - if (guid == "{2E6D7033-767A-494D-B478-F29D25DC9037}") - return QStringLiteral("MPEG Audio Layer 1/2"); - if (guid == "{0000000A-0000-0010-8000-00AA00389B71}") - return QStringLiteral("Windows Media Audio Voice"); - if (guid == "{00000001-0000-0010-8000-00AA00389B71}") - return QStringLiteral("Uncompressed PCM Audio"); - if (guid == "{00000164-0000-0010-8000-00AA00389B71}") - return QStringLiteral("Windows Media Audio 9 SPDIF"); - if (guid == "{00000161-0000-0010-8000-00AA00389B71}") - return QStringLiteral("Windows Media Audio 8 (WMA2)"); - if (guid == "{00000162-0000-0010-8000-00AA00389B71}") - return QStringLiteral("Windows Media Audio 9 (WMA3"); - if (guid == "{00000163-0000-0010-8000-00AA00389B71}") - return QStringLiteral("Windows Media Audio 9 Lossless"); - if (guid == "{8D2FD10B-5841-4a6b-8905-588FEC1ADED9}") - return QStringLiteral("Vorbis"); - if (guid == "{0000F1AC-0000-0010-8000-00AA00389B71}") - return QStringLiteral("Free Lossless Audio Codec (FLAC)"); - if (guid == "{00006C61-0000-0010-8000-00AA00389B71}") - return QStringLiteral("Apple Lossless Audio Codec (ALAC)"); - - // Video formats - if (guid == "{35327664-0000-0010-8000-00AA00389B71}") - return QStringLiteral("DVCPRO 25 (DV25)"); - if (guid == "{30357664-0000-0010-8000-00AA00389B71}") - return QStringLiteral("DVCPRO 50 (DV50)"); - if (guid == "{20637664-0000-0010-8000-00AA00389B71}") - return QStringLiteral("DVC/DV Video"); - if (guid == "{31687664-0000-0010-8000-00AA00389B71}") - return QStringLiteral("DVCPRO 100 (DVH1)"); - if (guid == "{64687664-0000-0010-8000-00AA00389B71}") - return QStringLiteral("HD-DVCR (DVHD)"); - if (guid == "{64737664-0000-0010-8000-00AA00389B71}") - return QStringLiteral("SDL-DVCR (DVSD)"); - if (guid == "{6C737664-0000-0010-8000-00AA00389B71}") - return QStringLiteral("SD-DVCR (DVSL)"); - if (guid == "{33363248-0000-0010-8000-00AA00389B71}") - return QStringLiteral("H.263 Video"); - if (guid == "{34363248-0000-0010-8000-00AA00389B71}") - return QStringLiteral("H.264 Video"); - if (guid == "{35363248-0000-0010-8000-00AA00389B71}") - return QStringLiteral("H.265 Video"); - if (guid == "{43564548-0000-0010-8000-00AA00389B71}") - return QStringLiteral("High Efficiency Video Coding (HEVC)"); - if (guid == "{3253344D-0000-0010-8000-00AA00389B71}") - return QStringLiteral("MPEG-4 part 2 Video (M4S2)"); - if (guid == "{47504A4D-0000-0010-8000-00AA00389B71}") - return QStringLiteral("Motion JPEG (MJPG)"); - if (guid == "{3334504D-0000-0010-8000-00AA00389B71}") - return QStringLiteral("Microsoft MPEG 4 version 3 (MP43)"); - if (guid == "{5334504D-0000-0010-8000-00AA00389B71}") - return QStringLiteral("ISO MPEG 4 version 1 (MP4S)"); - if (guid == "{5634504D-0000-0010-8000-00AA00389B71}") - return QStringLiteral("MPEG-4 part 2 Video (MP4V)"); - if (guid == "{E06D8026-DB46-11CF-B4D1-00805F6CBBEA}") - return QStringLiteral("MPEG-2 Video"); - if (guid == "{3147504D-0000-0010-8000-00AA00389B71}") - return QStringLiteral("MPEG-1 Video"); - if (guid == "{3153534D-0000-0010-8000-00AA00389B71}") - return QStringLiteral("Windows Media Screen 1 (MSS1)"); - if (guid == "{3253534D-0000-0010-8000-00AA00389B71}") - return QStringLiteral("Windows Media Video 9 Screen (MSS2)"); - if (guid == "{31564D57-0000-0010-8000-00AA00389B71}") - return QStringLiteral("Windows Media Video 7 (WMV1)"); - if (guid == "{32564D57-0000-0010-8000-00AA00389B71}") - return QStringLiteral("Windows Media Video 8 (WMV2)"); - if (guid == "{33564D57-0000-0010-8000-00AA00389B71}") - return QStringLiteral("Windows Media Video 9 (WMV3)"); - if (guid == "{31435657-0000-0010-8000-00AA00389B71}") - return QStringLiteral("Windows Media Video VC1 (WVC1)"); - if (guid == "{30385056-0000-0010-8000-00AA00389B71}") - return QStringLiteral("VP8 Video"); - if (guid == "{30395056-0000-0010-8000-00AA00389B71}") - return QStringLiteral("VP9 Video"); - return QStringLiteral("Unknown codec"); -} - -typedef HRESULT (WINAPI *q_SHCreateItemFromParsingName)(PCWSTR, IBindCtx *, const GUID&, void **); -static q_SHCreateItemFromParsingName sHCreateItemFromParsingName = nullptr; -#endif - -#if QT_CONFIG(wmsdk) - -namespace -{ - struct QWMMetaDataKey - { - QString qtName; - const wchar_t *wmName; - - QWMMetaDataKey(const QString &qtn, const wchar_t *wmn) : qtName(qtn), wmName(wmn) { } - }; -} - -using QWMMetaDataKeys = QList<QWMMetaDataKey>; -Q_GLOBAL_STATIC(QWMMetaDataKeys, metadataKeys) - -static const QWMMetaDataKeys *qt_wmMetaDataKeys() -{ - if (metadataKeys->isEmpty()) { - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Title, L"Title")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::SubTitle, L"WM/SubTitle")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Author, L"Author")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Comment, L"Comment")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Description, L"Description")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Category, L"WM/Category")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Genre, L"WM/Genre")); - //metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Date, 0)); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Year, L"WM/Year")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::UserRating, L"Rating")); - //metadataKeys->append(QWMMetaDataKey(QMediaMetaData::MetaDatawords, 0)); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Language, L"WM/Language")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Publisher, L"WM/Publisher")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Copyright, L"Copyright")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::ParentalRating, L"WM/ParentalRating")); - //metadataKeys->append(QWMMetaDataKey(QMediaMetaData::RatingOrganisation, L"RatingOrganisation")); - - // Media - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Size, L"FileSize")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::MediaType, L"MediaType")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Duration, L"Duration")); - - // Audio - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::AudioBitRate, L"AudioBitRate")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::AudioCodec, L"AudioCodec")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::ChannelCount, L"ChannelCount")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::SampleRate, L"Frequency")); - - // Music - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::AlbumTitle, L"WM/AlbumTitle")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::AlbumArtist, L"WM/AlbumArtist")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::ContributingArtist, L"Author")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Composer, L"WM/Composer")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Conductor, L"WM/Conductor")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Lyrics, L"WM/Lyrics")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Mood, L"WM/Mood")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::TrackNumber, L"WM/TrackNumber")); - //metadataKeys->append(QWMMetaDataKey(QMediaMetaData::TrackCount, 0)); - //metadataKeys->append(QWMMetaDataKey(QMediaMetaData::CoverArtUriSmall, 0)); - //metadataKeys->append(QWMMetaDataKey(QMediaMetaData::CoverArtUriLarge, 0)); - - // Image/Video - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Resolution, L"WM/VideoHeight")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::PixelAspectRatio, L"AspectRatioX")); - - // Video - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::VideoFrameRate, L"WM/VideoFrameRate")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::VideoBitRate, L"VideoBitRate")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::VideoCodec, L"VideoCodec")); - - //metadataKeys->append(QWMMetaDataKey(QMediaMetaData::PosterUri, 0)); - - // Movie - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::ChapterNumber, L"ChapterNumber")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Director, L"WM/Director")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::LeadPerformer, L"LeadPerformer")); - metadataKeys->append(QWMMetaDataKey(QMediaMetaData::Writer, L"WM/Writer")); - } - - return metadataKeys; -} - -static QVariant getValue(IWMHeaderInfo *header, const wchar_t *key) -{ - WORD streamNumber = 0; - WMT_ATTR_DATATYPE type = WMT_TYPE_DWORD; - WORD size = 0; - - if (header->GetAttributeByName(&streamNumber, key, &type, nullptr, &size) == S_OK) { - switch (type) { - case WMT_TYPE_DWORD: - if (size == sizeof(DWORD)) { - DWORD word; - if (header->GetAttributeByName( - &streamNumber, - key, - &type, - reinterpret_cast<BYTE *>(&word), - &size) == S_OK) { - return int(word); - } - } - break; - case WMT_TYPE_STRING: - { - QString string; - string.resize(size / 2); // size is in bytes, string is in UTF16 - - if (header->GetAttributeByName( - &streamNumber, - key, - &type, - reinterpret_cast<BYTE *>(string.data()), - &size) == S_OK) { - return string; - } - } - break; - case WMT_TYPE_BINARY: - { - QByteArray bytes; - bytes.resize(size); - if (header->GetAttributeByName( - &streamNumber, - key, - &type, - reinterpret_cast<BYTE *>(bytes.data()), - &size) == S_OK) { - return bytes; - } - } - break; - case WMT_TYPE_BOOL: - if (size == sizeof(DWORD)) { - DWORD word; - if (header->GetAttributeByName( - &streamNumber, - key, - &type, - reinterpret_cast<BYTE *>(&word), - &size) == S_OK) { - return bool(word); - } - } - break; - case WMT_TYPE_QWORD: - if (size == sizeof(QWORD)) { - QWORD word; - if (header->GetAttributeByName( - &streamNumber, - key, - &type, - reinterpret_cast<BYTE *>(&word), - &size) == S_OK) { - return qint64(word); - } - } - break; - case WMT_TYPE_WORD: - if (size == sizeof(WORD)){ - WORD word; - if (header->GetAttributeByName( - &streamNumber, - key, - &type, - reinterpret_cast<BYTE *>(&word), - &size) == S_OK) { - return short(word); - } - } - break; - case WMT_TYPE_GUID: - if (size == 16) { - } - break; - default: - break; - } - } - return QVariant(); -} -#endif - -#if QT_CONFIG(wshellitem) -static QVariant convertValue(const PROPVARIANT& var) -{ - QVariant value; - switch (var.vt) { - case VT_LPWSTR: - value = QString::fromUtf16(reinterpret_cast<const ushort*>(var.pwszVal)); - break; - case VT_UI4: - value = uint(var.ulVal); - break; - case VT_UI8: - value = qulonglong(var.uhVal.QuadPart); - break; - case VT_BOOL: - value = bool(var.boolVal); - break; - case VT_FILETIME: - SYSTEMTIME sysDate; - if (!FileTimeToSystemTime(&var.filetime, &sysDate)) - break; - value = QDate(sysDate.wYear, sysDate.wMonth, sysDate.wDay); - break; - case VT_STREAM: - { - STATSTG stat; - if (FAILED(var.pStream->Stat(&stat, STATFLAG_NONAME))) - break; - void *data = malloc(stat.cbSize.QuadPart); - ULONG read = 0; - if (FAILED(var.pStream->Read(data, stat.cbSize.QuadPart, &read))) { - free(data); - break; - } - value = QImage::fromData(reinterpret_cast<const uchar*>(data), read); - free(data); - } - break; - case VT_VECTOR | VT_LPWSTR: - QStringList vList; - for (ULONG i = 0; i < var.calpwstr.cElems; ++i) - vList.append(QString::fromUtf16(reinterpret_cast<const ushort*>(var.calpwstr.pElems[i]))); - value = vList; - break; - } - return value; -} -#endif - -DirectShowMetaDataControl::DirectShowMetaDataControl(QObject *parent) - : QMetaDataReaderControl(parent) -{ -} - -DirectShowMetaDataControl::~DirectShowMetaDataControl() = default; - -bool DirectShowMetaDataControl::isMetaDataAvailable() const -{ - return m_available; -} - -QVariant DirectShowMetaDataControl::metaData(const QString &key) const -{ - return m_metadata.value(key); -} - -QStringList DirectShowMetaDataControl::availableMetaData() const -{ - return m_metadata.keys(); -} - -static QString convertBSTR(BSTR *string) -{ - QString value = QString::fromUtf16(reinterpret_cast<ushort *>(*string), - ::SysStringLen(*string)); - - ::SysFreeString(*string); - string = nullptr; - - return value; -} - -void DirectShowMetaDataControl::setMetadata(const QVariantMap &metadata) -{ - m_metadata = metadata; - setMetadataAvailable(!m_metadata.isEmpty()); -} - -void DirectShowMetaDataControl::updateMetadata(const QString &fileSrc, QVariantMap &metadata) -{ -#if QT_CONFIG(wshellitem) - if (!sHCreateItemFromParsingName) { - QSystemLibrary lib(QStringLiteral("shell32")); - sHCreateItemFromParsingName = (q_SHCreateItemFromParsingName)(lib.resolve("SHCreateItemFromParsingName")); - } - - if (!fileSrc.isEmpty() && sHCreateItemFromParsingName) { - IShellItem2* shellItem = nullptr; - if (sHCreateItemFromParsingName(reinterpret_cast<const WCHAR*>(fileSrc.utf16()), - nullptr, IID_PPV_ARGS(&shellItem)) == S_OK) { - - IPropertyStore *pStore = nullptr; - if (shellItem->GetPropertyStore(GPS_DEFAULT, IID_PPV_ARGS(&pStore)) == S_OK) { - DWORD cProps; - if (SUCCEEDED(pStore->GetCount(&cProps))) { - for (DWORD i = 0; i < cProps; ++i) - { - PROPERTYKEY key; - PROPVARIANT var; - PropVariantInit(&var); - if (FAILED(pStore->GetAt(i, &key))) - continue; - if (FAILED(pStore->GetValue(key, &var))) - continue; - - if (IsEqualPropertyKey(key, PKEY_Author)) { - metadata.insert(QMediaMetaData::Author, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Title)) { - metadata.insert(QMediaMetaData::Title, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Media_SubTitle)) { - metadata.insert(QMediaMetaData::SubTitle, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_ParentalRating)) { - metadata.insert(QMediaMetaData::ParentalRating, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Comment)) { - metadata.insert(QMediaMetaData::Description, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Copyright)) { - metadata.insert(QMediaMetaData::Copyright, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Media_ProviderStyle)) { - metadata.insert(QMediaMetaData::Genre, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Media_Year)) { - metadata.insert(QMediaMetaData::Year, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Media_DateEncoded)) { - metadata.insert(QMediaMetaData::Date, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Rating)) { - metadata.insert(QMediaMetaData::UserRating, - int((convertValue(var).toUInt() - 1) / qreal(98) * 100)); - } else if (IsEqualPropertyKey(key, PKEY_Keywords)) { - metadata.insert(QMediaMetaData::Keywords, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Language)) { - metadata.insert(QMediaMetaData::Language, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Media_Publisher)) { - metadata.insert(QMediaMetaData::Publisher, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Media_Duration)) { - metadata.insert(QMediaMetaData::Duration, - (convertValue(var).toLongLong() + 10000) / 10000); - } else if (IsEqualPropertyKey(key, PKEY_Audio_EncodingBitrate)) { - metadata.insert(QMediaMetaData::AudioBitRate, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Media_AverageLevel)) { - metadata.insert(QMediaMetaData::AverageLevel, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Audio_ChannelCount)) { - metadata.insert(QMediaMetaData::ChannelCount, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Audio_PeakValue)) { - metadata.insert(QMediaMetaData::PeakValue, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Audio_SampleRate)) { - metadata.insert(QMediaMetaData::SampleRate, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Music_AlbumTitle)) { - metadata.insert(QMediaMetaData::AlbumTitle, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Music_AlbumArtist)) { - metadata.insert(QMediaMetaData::AlbumArtist, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Music_Artist)) { - metadata.insert(QMediaMetaData::ContributingArtist, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Music_Composer)) { - metadata.insert(QMediaMetaData::Composer, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Music_Conductor)) { - metadata.insert(QMediaMetaData::Conductor, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Music_Lyrics)) { - metadata.insert(QMediaMetaData::Lyrics, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Music_Mood)) { - metadata.insert(QMediaMetaData::Mood, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Music_TrackNumber)) { - metadata.insert(QMediaMetaData::TrackNumber, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Music_Genre)) { - metadata.insert(QMediaMetaData::Genre, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_ThumbnailStream)) { - metadata.insert(QMediaMetaData::ThumbnailImage, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Video_FrameHeight)) { - QSize res; - res.setHeight(convertValue(var).toUInt()); - if (SUCCEEDED(pStore->GetValue(PKEY_Video_FrameWidth, &var))) - res.setWidth(convertValue(var).toUInt()); - metadata.insert(QMediaMetaData::Resolution, res); - } else if (IsEqualPropertyKey(key, PKEY_Video_HorizontalAspectRatio)) { - QSize aspectRatio; - aspectRatio.setWidth(convertValue(var).toUInt()); - if (SUCCEEDED(pStore->GetValue(PKEY_Video_VerticalAspectRatio, &var))) - aspectRatio.setHeight(convertValue(var).toUInt()); - metadata.insert(QMediaMetaData::PixelAspectRatio, aspectRatio); - } else if (IsEqualPropertyKey(key, PKEY_Video_FrameRate)) { - metadata.insert(QMediaMetaData::VideoFrameRate, - convertValue(var).toReal() / 1000); - } else if (IsEqualPropertyKey(key, PKEY_Video_EncodingBitrate)) { - metadata.insert(QMediaMetaData::VideoBitRate, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Video_Director)) { - metadata.insert(QMediaMetaData::Director, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Media_Writer)) { - metadata.insert(QMediaMetaData::Writer, convertValue(var)); - } else if (IsEqualPropertyKey(key, PKEY_Video_Compression)) { - metadata.insert(QMediaMetaData::VideoCodec, nameForGUIDString(convertValue(var).toString())); - } else if (IsEqualPropertyKey(key, PKEY_Audio_Format)) { - metadata.insert(QMediaMetaData::AudioCodec, nameForGUIDString(convertValue(var).toString())); - } - - PropVariantClear(&var); - } - } - - pStore->Release(); - } - - shellItem->Release(); - } - } -#else - Q_UNUSED(fileSrc); - Q_UNUSED(metadata); -#endif -} - -void DirectShowMetaDataControl::updateMetadata(IFilterGraph2 *graph, IBaseFilter *source, QVariantMap &metadata) -{ -#if QT_CONFIG(wmsdk) - if (IWMHeaderInfo *info = com_cast<IWMHeaderInfo>(source, IID_IWMHeaderInfo)) { - const auto keys = *qt_wmMetaDataKeys(); - for (const QWMMetaDataKey &key : keys) { - QVariant var = getValue(info, key.wmName); - if (var.isValid()) { - if (key.qtName == QMediaMetaData::Duration) { - // duration is provided in 100-nanosecond units, convert to milliseconds - var = (var.toLongLong() + 10000) / 10000; - } else if (key.qtName == QMediaMetaData::Resolution) { - QSize res; - res.setHeight(var.toUInt()); - res.setWidth(getValue(info, L"WM/VideoWidth").toUInt()); - var = res; - } else if (key.qtName == QMediaMetaData::VideoFrameRate) { - var = var.toReal() / 1000.f; - } else if (key.qtName == QMediaMetaData::PixelAspectRatio) { - QSize aspectRatio; - aspectRatio.setWidth(var.toUInt()); - aspectRatio.setHeight(getValue(info, L"AspectRatioY").toUInt()); - var = aspectRatio; - } else if (key.qtName == QMediaMetaData::UserRating) { - var = (var.toUInt() - 1) / qreal(98) * 100; - } - - metadata.insert(key.qtName, var); - } - } - - info->Release(); - } - - if (!metadata.isEmpty()) - return; -#endif - { - IAMMediaContent *content = nullptr; - - if ((!graph || graph->QueryInterface( - IID_IAMMediaContent, reinterpret_cast<void **>(&content)) != S_OK) - && (!source || source->QueryInterface( - IID_IAMMediaContent, reinterpret_cast<void **>(&content)) != S_OK)) { - content = nullptr; - } - - if (content) { - BSTR string = nullptr; - - if (content->get_AuthorName(&string) == S_OK) - metadata.insert(QMediaMetaData::Author, convertBSTR(&string)); - - if (content->get_Title(&string) == S_OK) - metadata.insert(QMediaMetaData::Title, convertBSTR(&string)); - - if (content->get_Description(&string) == S_OK) - metadata.insert(QMediaMetaData::Description, convertBSTR(&string)); - - if (content->get_Rating(&string) == S_OK) - metadata.insert(QMediaMetaData::UserRating, convertBSTR(&string)); - - if (content->get_Copyright(&string) == S_OK) - metadata.insert(QMediaMetaData::Copyright, convertBSTR(&string)); - - content->Release(); - } - } -} - -void DirectShowMetaDataControl::setMetadataAvailable(bool available) -{ - if (m_available == available) - return; - - m_available = available; - - // If the metadata is not available, notify about it immediately. - Qt::ConnectionType type = m_available ? Qt::QueuedConnection : Qt::AutoConnection; - QMetaObject::invokeMethod(this, "metaDataAvailableChanged", type, Q_ARG(bool, m_available)); - // Currently the metadata is changed only with its availability. - QMetaObject::invokeMethod(this, "metaDataChanged", type); -} diff --git a/src/plugins/directshow/player/directshowmetadatacontrol.h b/src/plugins/directshow/player/directshowmetadatacontrol.h deleted file mode 100644 index e66127ab3..000000000 --- a/src/plugins/directshow/player/directshowmetadatacontrol.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWMETADATACONTROL_H -#define DIRECTSHOWMETADATACONTROL_H - -#include <dshow.h> - -#include <qmetadatareadercontrol.h> - -#include "directshowglobal.h" - -#include <QtCore/qcoreevent.h> - -QT_BEGIN_NAMESPACE - -class DirectShowMetaDataControl : public QMetaDataReaderControl -{ - Q_OBJECT -public: - DirectShowMetaDataControl(QObject *parent = nullptr); - ~DirectShowMetaDataControl() override; - - bool isMetaDataAvailable() const override; - - QVariant metaData(const QString &key) const override; - QStringList availableMetaData() const override; - - void setMetadata(const QVariantMap &metadata); - - static void updateMetadata(const QString &fileSrc, QVariantMap &metadata); - static void updateMetadata(IFilterGraph2 *graph, IBaseFilter *source, QVariantMap &metadata); - -private: - void setMetadataAvailable(bool available); - - enum Event - { - MetaDataChanged = QEvent::User - }; - - QVariantMap m_metadata; - bool m_available = false; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/directshow/player/directshowplayercontrol.cpp b/src/plugins/directshow/player/directshowplayercontrol.cpp deleted file mode 100644 index 50e8d6421..000000000 --- a/src/plugins/directshow/player/directshowplayercontrol.cpp +++ /dev/null @@ -1,397 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <dshow.h> - -#include "directshowplayercontrol.h" - -#include "directshowplayerservice.h" - -#include <QtCore/qcoreapplication.h> -#include <QtCore/qmath.h> -#include <qaudio.h> - -DirectShowPlayerControl::DirectShowPlayerControl(DirectShowPlayerService *service, QObject *parent) - : QMediaPlayerControl(parent) - , m_service(service) -{ -} - -DirectShowPlayerControl::~DirectShowPlayerControl() -{ - if (m_audio) - m_audio->Release(); -} - -QMediaPlayer::State DirectShowPlayerControl::state() const -{ - return m_state; -} - -QMediaPlayer::MediaStatus DirectShowPlayerControl::mediaStatus() const -{ - return m_status; -} - -qint64 DirectShowPlayerControl::duration() const -{ - return m_duration; -} - -qint64 DirectShowPlayerControl::position() const -{ - if (m_pendingPosition != -1) - return m_pendingPosition; - - return m_service->position(); -} - -void DirectShowPlayerControl::setPosition(qint64 position) -{ - if (m_status == QMediaPlayer::EndOfMedia) { - m_status = QMediaPlayer::LoadedMedia; - emit mediaStatusChanged(m_status); - } - - if (m_state == QMediaPlayer::StoppedState) { - if (m_pendingPosition != position) { - m_pendingPosition = position; - emit positionChanged(m_pendingPosition); - } - return; - } - - m_service->seek(position); - m_pendingPosition = -1; -} - -int DirectShowPlayerControl::volume() const -{ - return m_volume; -} - -void DirectShowPlayerControl::setVolume(int volume) -{ - int boundedVolume = qBound(0, volume, 100); - - if (m_volume == boundedVolume) - return; - - m_volume = boundedVolume; - - if (!m_muted) - setVolumeHelper(m_volume); - - emit volumeChanged(m_volume); -} - -bool DirectShowPlayerControl::isMuted() const -{ - return m_muted; -} - -void DirectShowPlayerControl::setMuted(bool muted) -{ - if (m_muted == muted) - return; - - m_muted = muted; - - setVolumeHelper(m_muted ? 0 : m_volume); - - emit mutedChanged(m_muted); -} - -void DirectShowPlayerControl::setVolumeHelper(int volume) -{ - if (!m_audio) - return; - - long adjustedVolume; - if (volume == 0) { - adjustedVolume = -10000; // -100 dB (lower limit for put_Volume()) - } else if (volume == 100) { - adjustedVolume = 0; - } else { - adjustedVolume = QAudio::convertVolume(volume / qreal(100), - QAudio::LinearVolumeScale, - QAudio::DecibelVolumeScale) * 100; - } - - m_audio->put_Volume(adjustedVolume); -} - -int DirectShowPlayerControl::bufferStatus() const -{ - return m_service->bufferStatus(); -} - -bool DirectShowPlayerControl::isAudioAvailable() const -{ - return m_streamTypes & DirectShowPlayerService::AudioStream; -} - -bool DirectShowPlayerControl::isVideoAvailable() const -{ - return m_streamTypes & DirectShowPlayerService::VideoStream; -} - -bool DirectShowPlayerControl::isSeekable() const -{ - return m_seekable; -} - -QMediaTimeRange DirectShowPlayerControl::availablePlaybackRanges() const -{ - return m_service->availablePlaybackRanges(); -} - -qreal DirectShowPlayerControl::playbackRate() const -{ - return m_playbackRate; -} - -void DirectShowPlayerControl::setPlaybackRate(qreal rate) -{ - if (!qFuzzyCompare(m_playbackRate, rate)) { - m_service->setRate(rate); - - emit playbackRateChanged(m_playbackRate = rate); - } -} - -QMediaContent DirectShowPlayerControl::media() const -{ - return m_media; -} - -const QIODevice *DirectShowPlayerControl::mediaStream() const -{ - return m_stream; -} - -void DirectShowPlayerControl::setMedia(const QMediaContent &media, QIODevice *stream) -{ - if (m_media == media && m_stream == stream) - return; - - m_pendingPosition = -1; - m_emitPosition = -1; - - m_media = media; - m_stream = stream; - - m_updateProperties &= PlaybackRateProperty; - - m_service->load(media, stream); - - emit mediaChanged(m_media); - emitPropertyChanges(); -} - -void DirectShowPlayerControl::play() -{ - playOrPause(QMediaPlayer::PlayingState); -} - -void DirectShowPlayerControl::pause() -{ - playOrPause(QMediaPlayer::PausedState); -} - -void DirectShowPlayerControl::playOrPause(QMediaPlayer::State state) -{ - if (m_status == QMediaPlayer::NoMedia || state == QMediaPlayer::StoppedState) - return; - if (m_status == QMediaPlayer::InvalidMedia) { - setMedia(m_media, m_stream); - if (m_error != QMediaPlayer::NoError) - return; - } - - m_emitPosition = -1; - m_state = state; - - if (m_pendingPosition != -1) - setPosition(m_pendingPosition); - - if (state == QMediaPlayer::PausedState) - m_service->pause(); - else - m_service->play(); - - emit stateChanged(m_state); -} - -void DirectShowPlayerControl::stop() -{ - m_emitPosition = -1; - m_service->stop(); - emit stateChanged(m_state = QMediaPlayer::StoppedState); -} - -void DirectShowPlayerControl::customEvent(QEvent *event) -{ - if (event->type() == QEvent::Type(PropertiesChanged)) { - emitPropertyChanges(); - - event->accept(); - } else { - QMediaPlayerControl::customEvent(event); - } -} - -void DirectShowPlayerControl::emitPropertyChanges() -{ - int properties = m_updateProperties; - m_updateProperties = 0; - - if (properties & StatusProperty) - emit mediaStatusChanged(m_status); - - if ((properties & ErrorProperty) && m_error != QMediaPlayer::NoError) - emit error(m_error, m_errorString); - - if (properties & PlaybackRateProperty) - emit playbackRateChanged(m_playbackRate); - - if (properties & StreamTypesProperty) { - emit audioAvailableChanged(m_streamTypes & DirectShowPlayerService::AudioStream); - emit videoAvailableChanged(m_streamTypes & DirectShowPlayerService::VideoStream); - } - - if (properties & PositionProperty && m_emitPosition != -1) - emit positionChanged(m_emitPosition); - - if (properties & DurationProperty) - emit durationChanged(m_duration); - - if (properties & SeekableProperty) - emit seekableChanged(m_seekable); - - if (properties & StateProperty) - emit stateChanged(m_state); -} - -void DirectShowPlayerControl::scheduleUpdate(int properties) -{ - if (m_updateProperties == 0) - QCoreApplication::postEvent(this, new QEvent(QEvent::Type(PropertiesChanged))); - - m_updateProperties |= properties; -} - -void DirectShowPlayerControl::updateState(QMediaPlayer::State state) -{ - if (m_state != state) { - m_state = state; - - scheduleUpdate(StateProperty); - } -} - -void DirectShowPlayerControl::updateStatus(QMediaPlayer::MediaStatus status) -{ - if (m_status != status) { - m_status = status; - - scheduleUpdate(StatusProperty); - } -} - -void DirectShowPlayerControl::updateMediaInfo(qint64 duration, int streamTypes, bool seekable) -{ - int properties = 0; - - if (m_duration != duration) { - m_duration = duration; - - properties |= DurationProperty; - } - if (m_streamTypes != streamTypes) { - m_streamTypes = streamTypes; - - properties |= StreamTypesProperty; - } - - if (m_seekable != seekable) { - m_seekable = seekable; - - properties |= SeekableProperty; - } - - if (properties != 0) - scheduleUpdate(properties); -} - -void DirectShowPlayerControl::updatePlaybackRate(qreal rate) -{ - if (!qFuzzyCompare(m_playbackRate, rate)) { - m_playbackRate = rate; - - scheduleUpdate(PlaybackRateProperty); - } -} - -void DirectShowPlayerControl::updateAudioOutput(IBaseFilter *filter) -{ - if (m_audio) - m_audio->Release(); - - m_audio = com_cast<IBasicAudio>(filter, IID_IBasicAudio); - setVolumeHelper(m_muted ? 0 : m_volume); -} - -void DirectShowPlayerControl::updateError(QMediaPlayer::Error error, const QString &errorString) -{ - m_error = error; - m_errorString = errorString; - - if (m_error != QMediaPlayer::NoError) - scheduleUpdate(ErrorProperty); -} - -void DirectShowPlayerControl::updatePosition(qint64 position) -{ - if (m_emitPosition != position) { - m_emitPosition = position; - - scheduleUpdate(PositionProperty); - } -} diff --git a/src/plugins/directshow/player/directshowplayercontrol.h b/src/plugins/directshow/player/directshowplayercontrol.h deleted file mode 100644 index 122f5be2f..000000000 --- a/src/plugins/directshow/player/directshowplayercontrol.h +++ /dev/null @@ -1,153 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWPLAYERCONTROL_H -#define DIRECTSHOWPLAYERCONTROL_H - -#include <dshow.h> - -#include "qmediacontent.h" -#include "qmediaplayercontrol.h" - -#include <QtCore/qcoreevent.h> - -#include "directshowplayerservice.h" - -QT_BEGIN_NAMESPACE - -class DirectShowPlayerControl : public QMediaPlayerControl -{ - Q_OBJECT -public: - DirectShowPlayerControl(DirectShowPlayerService *service, QObject *parent = nullptr); - ~DirectShowPlayerControl() override; - - QMediaPlayer::State state() const override; - - QMediaPlayer::MediaStatus mediaStatus() const override; - - qint64 duration() const override; - - qint64 position() const override; - void setPosition(qint64 position) override; - - int volume() const override; - void setVolume(int volume) override; - - bool isMuted() const override; - void setMuted(bool muted) override; - - int bufferStatus() const override; - - bool isAudioAvailable() const override; - bool isVideoAvailable() const override; - - bool isSeekable() const override; - - QMediaTimeRange availablePlaybackRanges() const override; - - qreal playbackRate() const override; - void setPlaybackRate(qreal rate) override; - - QMediaContent media() const override; - const QIODevice *mediaStream() const override; - void setMedia(const QMediaContent &media, QIODevice *stream) override; - - void play() override; - void pause() override; - void stop() override; - - void updateState(QMediaPlayer::State state); - void updateStatus(QMediaPlayer::MediaStatus status); - void updateMediaInfo(qint64 duration, int streamTypes, bool seekable); - void updatePlaybackRate(qreal rate); - void updateAudioOutput(IBaseFilter *filter); - void updateError(QMediaPlayer::Error error, const QString &errorString); - void updatePosition(qint64 position); - -protected: - void customEvent(QEvent *event) override; - -private: - enum Properties - { - StateProperty = 0x01, - StatusProperty = 0x02, - StreamTypesProperty = 0x04, - DurationProperty = 0x08, - PlaybackRateProperty = 0x10, - SeekableProperty = 0x20, - ErrorProperty = 0x40, - PositionProperty = 0x80 - }; - - enum Event - { - PropertiesChanged = QEvent::User - }; - - void playOrPause(QMediaPlayer::State state); - - void scheduleUpdate(int properties); - void emitPropertyChanges(); - void setVolumeHelper(int volume); - - DirectShowPlayerService *m_service; - IBasicAudio *m_audio = nullptr; - QIODevice *m_stream = nullptr; - int m_updateProperties = 0; - QMediaPlayer::State m_state = QMediaPlayer::StoppedState; - QMediaPlayer::MediaStatus m_status = QMediaPlayer::NoMedia; - QMediaPlayer::Error m_error = QMediaPlayer::NoError; - int m_streamTypes = 0; - int m_volume = 100; - bool m_muted = false; - qint64 m_emitPosition = -1; - qint64 m_pendingPosition = -1; - qint64 m_duration = 0; - qreal m_playbackRate = 0; - bool m_seekable = false; - QMediaContent m_media; - QString m_errorString; - -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/directshow/player/directshowplayerservice.cpp b/src/plugins/directshow/player/directshowplayerservice.cpp deleted file mode 100644 index 04e27b9c4..000000000 --- a/src/plugins/directshow/player/directshowplayerservice.cpp +++ /dev/null @@ -1,1812 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <dshow.h> -#ifdef min -#undef min -#endif -#ifdef max -#undef max -#endif - -#include "directshowplayerservice.h" - -#include "directshowaudioendpointcontrol.h" -#include "directshowmetadatacontrol.h" -#include "vmr9videowindowcontrol.h" -#include "directshowiosource.h" -#include "directshowplayercontrol.h" -#include "directshowvideorenderercontrol.h" -#include "directshowutils.h" -#include "directshowglobal.h" -#include "directshowaudioprobecontrol.h" -#include "directshowvideoprobecontrol.h" -#include "directshowsamplegrabber.h" - -#if QT_CONFIG(evr) -#include "directshowevrvideowindowcontrol.h" -#else -#include <mmreg.h> -#endif - -#include "qmediacontent.h" - -#include <QtMultimedia/private/qtmultimedia-config_p.h> - -#include <QtCore/qcoreapplication.h> -#include <QtCore/qdatetime.h> -#include <QtCore/qdir.h> -#include <QtCore/qthread.h> -#include <QtCore/qvarlengtharray.h> -#include <QtCore/qsize.h> - -#include <QtMultimedia/qaudiobuffer.h> -#include <QtMultimedia/qvideoframe.h> -#include <QtMultimedia/private/qmemoryvideobuffer_p.h> - -#if QT_CONFIG(wmsdk) -# include <wmsdk.h> -#endif - -#ifndef Q_CC_MINGW -# include <comdef.h> -#endif - -QT_BEGIN_NAMESPACE - -Q_GLOBAL_STATIC(DirectShowEventLoop, qt_directShowEventLoop) - -static QString comError(HRESULT hr) -{ -#ifndef Q_CC_MINGW // MinGW 5.3 no longer has swprintf_s(). - _com_error error(hr); - return QString::fromWCharArray(error.ErrorMessage()); -#else - Q_UNUSED(hr); - return QString(); -#endif -} - -// QMediaPlayer uses millisecond time units, direct show uses 100 nanosecond units. -static const int qt_directShowTimeScale = 10000; - -class DirectShowPlayerServiceThread : public QThread -{ -public: - DirectShowPlayerServiceThread(DirectShowPlayerService *service) - : m_service(service) - { - } - -protected: - void run() override { m_service->run(); } - -private: - DirectShowPlayerService *m_service; -}; - -DirectShowPlayerService::DirectShowPlayerService(QObject *parent) - : QMediaService(parent) - , m_loop(qt_directShowEventLoop()) - , m_taskHandle(::CreateEvent(nullptr, FALSE, FALSE, nullptr)) -{ - m_playerControl = new DirectShowPlayerControl(this); - m_metaDataControl = new DirectShowMetaDataControl(this); - m_audioEndpointControl = new DirectShowAudioEndpointControl(this); - - m_taskThread = new DirectShowPlayerServiceThread(this); - m_taskThread->start(); -} - -DirectShowPlayerService::~DirectShowPlayerService() -{ - { - QMutexLocker locker(&m_mutex); - - releaseGraph(); - - m_pendingTasks = Shutdown; - ::SetEvent(m_taskHandle); - } - - m_taskThread->wait(); - delete m_taskThread; - - if (m_audioOutput) { - m_audioOutput->Release(); - m_audioOutput = nullptr; - } - - if (m_videoOutput) { - m_videoOutput->Release(); - m_videoOutput = nullptr; - } - - delete m_playerControl; - delete m_audioEndpointControl; - delete m_metaDataControl; - delete m_videoRendererControl; - delete m_videoWindowControl; - delete m_audioProbeControl; - delete m_videoProbeControl; - - ::CloseHandle(m_taskHandle); -} - -QMediaControl *DirectShowPlayerService::requestControl(const char *name) -{ - if (qstrcmp(name, QMediaPlayerControl_iid) == 0) - return m_playerControl; - if (qstrcmp(name, QAudioOutputSelectorControl_iid) == 0) - return m_audioEndpointControl; - if (qstrcmp(name, QMetaDataReaderControl_iid) == 0) - return m_metaDataControl; - if (qstrcmp(name, QVideoRendererControl_iid) == 0) { - if (!m_videoRendererControl && !m_videoWindowControl) { - m_videoRendererControl = new DirectShowVideoRendererControl(m_loop); - - connect(m_videoRendererControl, &DirectShowVideoRendererControl::filterChanged, - this, &DirectShowPlayerService::videoOutputChanged); - - return m_videoRendererControl; - } - return nullptr; - } - if (qstrcmp(name, QVideoWindowControl_iid) == 0) { - if (!m_videoRendererControl && !m_videoWindowControl) { - IBaseFilter *filter{}; - -#if QT_CONFIG(evr) - if (!qgetenv("QT_DIRECTSHOW_NO_EVR").toInt()) { - 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; - } - return nullptr; - } - if (qstrcmp(name, QMediaAudioProbeControl_iid) == 0) { - if (!m_audioProbeControl) - m_audioProbeControl = new DirectShowAudioProbeControl(); - m_audioProbeControl->ref(); - updateAudioProbe(); - return m_audioProbeControl; - } - if (qstrcmp(name, QMediaVideoProbeControl_iid) == 0) { - if (!m_videoProbeControl) - m_videoProbeControl = new DirectShowVideoProbeControl(); - m_videoProbeControl->ref(); - updateVideoProbe(); - return m_videoProbeControl; - } - return nullptr; -} - -void DirectShowPlayerService::releaseControl(QMediaControl *control) -{ - if (!control) { - qWarning("QMediaService::releaseControl():" - " Attempted release of null control"); - } else if (control == m_videoRendererControl) { - setVideoOutput(nullptr); - - delete m_videoRendererControl; - - m_videoRendererControl = nullptr; - } else if (control == m_videoWindowControl) { - setVideoOutput(nullptr); - - delete m_videoWindowControl; - - m_videoWindowControl = nullptr; - } else if (control == m_audioProbeControl) { - if (!m_audioProbeControl->deref()) { - DirectShowAudioProbeControl *old = m_audioProbeControl; - m_audioProbeControl = nullptr; - updateAudioProbe(); - delete old; - } - } else if (control == m_videoProbeControl) { - if (!m_videoProbeControl->deref()) { - DirectShowVideoProbeControl *old = m_videoProbeControl; - m_videoProbeControl = nullptr; - updateVideoProbe(); - delete old; - } - } -} - -void DirectShowPlayerService::load(const QMediaContent &media, QIODevice *stream) -{ - QMutexLocker locker(&m_mutex); - - m_pendingTasks = 0; - - if (m_graph) - releaseGraph(); - - m_url = media.request().url(); - - m_stream = stream; - m_error = QMediaPlayer::NoError; - m_errorString = QString(); - m_position = 0; - m_seekPosition = -1; - m_duration = 0; - m_streamTypes = 0; - m_executedTasks = 0; - m_buffering = false; - m_seekable = false; - m_atEnd = false; - m_dontCacheNextSeekResult = false; - m_metaDataControl->setMetadata(QVariantMap()); - - if (m_url.isEmpty() && !stream) { - m_pendingTasks = 0; - m_graphStatus = NoMedia; - } else if (stream && (!stream->isReadable() || stream->isSequential())) { - m_pendingTasks = 0; - m_graphStatus = InvalidMedia; - m_error = QMediaPlayer::ResourceError; - } else { - // {36b73882-c2c8-11cf-8b46-00805f6cef60} - static const GUID iid_IFilterGraph2 = { - 0x36b73882, 0xc2c8, 0x11cf, {0x8b, 0x46, 0x00, 0x80, 0x5f, 0x6c, 0xef, 0x60} }; - m_graphStatus = Loading; - - DirectShowUtils::CoInitializeIfNeeded(); - m_graph = com_new<IFilterGraph2>(CLSID_FilterGraph, iid_IFilterGraph2); - m_graphBuilder = com_new<ICaptureGraphBuilder2>(CLSID_CaptureGraphBuilder2, IID_ICaptureGraphBuilder2); - - // Attach the filter graph to the capture graph. - HRESULT hr = m_graphBuilder->SetFiltergraph(m_graph); - if (FAILED(hr)) { - qCWarning(qtDirectShowPlugin, "[0x%x] Failed to attach filter to capture graph", hr); - m_graphBuilder->Release(); - m_graphBuilder = nullptr; - } - - if (stream) - m_pendingTasks = SetStreamSource; - else - m_pendingTasks = SetUrlSource; - - ::SetEvent(m_taskHandle); - } - - m_playerControl->updateError(m_error, m_errorString); - m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable); - m_playerControl->updateState(QMediaPlayer::StoppedState); - m_playerControl->updatePosition(m_position); - updateStatus(); -} - -void DirectShowPlayerService::doSetUrlSource(QMutexLocker<QMutex> *locker) -{ - IBaseFilter *source = nullptr; - - HRESULT hr = E_FAIL; - if (m_url.scheme() == QLatin1String("http") || m_url.scheme() == QLatin1String("https")) { - static const GUID clsid_WMAsfReader = { - 0x187463a0, 0x5bb7, 0x11d3, {0xac, 0xbe, 0x00, 0x80, 0xc7, 0x5e, 0x24, 0x6e} }; - - // {56a868a6-0ad4-11ce-b03a-0020af0ba770} - 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)) { - locker->unlock(); - hr = fileSource->Load(reinterpret_cast<const OLECHAR *>(m_url.toString().utf16()), nullptr); - - if (SUCCEEDED(hr)) { - source = com_cast<IBaseFilter>(fileSource, IID_IBaseFilter); - - if (!SUCCEEDED(hr = m_graph->AddFilter(source, L"Source")) && source) { - source->Release(); - source = nullptr; - } - } - fileSource->Release(); - locker->relock(); - } - } - - if (!SUCCEEDED(hr)) { - locker->unlock(); - const QString urlString = m_url.isLocalFile() - ? QDir::toNativeSeparators(m_url.toLocalFile()) : m_url.toString(); - hr = m_graph->AddSourceFilter( - reinterpret_cast<const OLECHAR *>(urlString.utf16()), L"Source", &source); - locker->relock(); - } - - if (SUCCEEDED(hr)) { - m_executedTasks = SetSource; - m_pendingTasks |= Render; - - if (m_audioOutput) - m_pendingTasks |= SetAudioOutput; - if (m_videoOutput) - m_pendingTasks |= SetVideoOutput; - if (m_audioProbeControl) - m_pendingTasks |= SetAudioProbe; - if (m_videoProbeControl) - m_pendingTasks |= SetVideoProbe; - - if (m_rate != 1.0) - m_pendingTasks |= SetRate; - - m_source = source; - } else { - m_graphStatus = InvalidMedia; - - switch (hr) { - case VFW_E_UNKNOWN_FILE_TYPE: - m_error = QMediaPlayer::FormatError; - m_errorString = QString(); - break; - default: - m_error = QMediaPlayer::ResourceError; - m_errorString = QString(); - qWarning("DirectShowPlayerService::doSetUrlSource: Unresolved error code 0x%x (%s)", - uint(hr), qPrintable(comError(hr))); - break; - } - - QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error))); - } -} - -void DirectShowPlayerService::doSetStreamSource(QMutexLocker<QMutex> *locker) -{ - Q_UNUSED(locker); - DirectShowIOSource *source = new DirectShowIOSource(m_loop); - source->setDevice(m_stream); - - const HRESULT hr = m_graph->AddFilter(source, L"Source"); - if (SUCCEEDED(hr)) { - m_executedTasks = SetSource; - m_pendingTasks |= Render; - - if (m_audioOutput) - m_pendingTasks |= SetAudioOutput; - if (m_videoOutput) - m_pendingTasks |= SetVideoOutput; - - if (m_rate != 1.0) - m_pendingTasks |= SetRate; - - m_source = source; - } else { - source->Release(); - - m_pendingTasks = 0; - m_graphStatus = InvalidMedia; - - m_error = QMediaPlayer::ResourceError; - m_errorString = QString(); - qWarning("DirectShowPlayerService::doPlay: Unresolved error code 0x%x (%s)", - uint(hr), qPrintable(comError(hr))); - - QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error))); - } -} - -void DirectShowPlayerService::doRender(QMutexLocker<QMutex> *locker) -{ - m_pendingTasks |= m_executedTasks & (Play | Pause); - - if (IMediaControl *control = com_cast<IMediaControl>(m_graph, IID_IMediaControl)) { - control->Stop(); - control->Release(); - } - - if (m_pendingTasks & SetAudioOutput) { - m_graph->AddFilter(m_audioOutput, L"AudioOutput"); - - m_pendingTasks ^= SetAudioOutput; - m_executedTasks |= SetAudioOutput; - } - if (m_pendingTasks & SetVideoOutput) { - m_graph->AddFilter(m_videoOutput, L"VideoOutput"); - - m_pendingTasks ^= SetVideoOutput; - m_executedTasks |= SetVideoOutput; - } - - if (m_pendingTasks & SetAudioProbe) { - doSetAudioProbe(locker); - m_pendingTasks ^= SetAudioProbe; - m_executedTasks |= SetAudioProbe; - } - - if (m_pendingTasks & SetVideoProbe) { - doSetVideoProbe(locker); - m_pendingTasks ^= SetVideoProbe; - m_executedTasks |= SetVideoProbe; - } - - IFilterGraph2 *graph = m_graph; - graph->AddRef(); - - QVarLengthArray<IBaseFilter *, 16> filters; - m_source->AddRef(); - filters.append(m_source); - - bool rendered = false; - - HRESULT renderHr = S_OK; - - while (!filters.isEmpty()) { - IEnumPins *pins = nullptr; - IBaseFilter *filter = filters[filters.size() - 1]; - filters.removeLast(); - - if (!(m_pendingTasks & ReleaseFilters) && SUCCEEDED(filter->EnumPins(&pins))) { - int outputs = 0; - for (IPin *pin = nullptr; pins->Next(1, &pin, nullptr) == S_OK; pin->Release()) { - PIN_DIRECTION direction; - if (pin->QueryDirection(&direction) == S_OK && direction == PINDIR_OUTPUT) { - ++outputs; - - IPin *peer = nullptr; - if (pin->ConnectedTo(&peer) == S_OK) { - PIN_INFO peerInfo; - if (SUCCEEDED(peer->QueryPinInfo(&peerInfo))) - filters.append(peerInfo.pFilter); - peer->Release(); - } else { - locker->unlock(); - HRESULT hr = graph->RenderEx(pin, /*AM_RENDEREX_RENDERTOEXISTINGRENDERERS*/ 1, nullptr); - if (SUCCEEDED(hr)) { - rendered = true; - m_error = QMediaPlayer::NoError; - } else if (!(m_executedTasks & SetVideoOutput)) { - // Do not return an error if no video output is set yet. - rendered = true; - // Remember the error in this case. - // Handle it when playing is requested and no video output has been provided. - m_error = QMediaPlayer::ResourceError; - m_errorString = QString("%1: %2").arg(__FUNCTION__).arg(qt_error_string(hr)); - } else if (renderHr == S_OK || renderHr == VFW_E_NO_DECOMPRESSOR){ - renderHr = hr; - } - locker->relock(); - } - } - } - - pins->Release(); - - if (outputs == 0) - rendered = true; - } - filter->Release(); - } - - if (m_audioOutput && !isConnected(m_audioOutput, PINDIR_INPUT)) { - graph->RemoveFilter(m_audioOutput); - - m_executedTasks &= ~SetAudioOutput; - } - - if (m_videoOutput && !isConnected(m_videoOutput, PINDIR_INPUT)) { - graph->RemoveFilter(m_videoOutput); - - m_executedTasks &= ~SetVideoOutput; - } - - graph->Release(); - - if (!(m_pendingTasks & ReleaseFilters)) { - if (rendered) { - if (!(m_executedTasks & FinalizeLoad)) - m_pendingTasks |= FinalizeLoad; - } else { - m_pendingTasks = 0; - - m_graphStatus = InvalidMedia; - - if (!m_audioOutput && !m_videoOutput) { - m_error = QMediaPlayer::ResourceError; - m_errorString = QString(); - } else { - switch (renderHr) { - case VFW_E_UNSUPPORTED_AUDIO: - case VFW_E_UNSUPPORTED_VIDEO: - case VFW_E_UNSUPPORTED_STREAM: - m_error = QMediaPlayer::FormatError; - m_errorString = QString(); - break; - default: - m_error = QMediaPlayer::ResourceError; - m_errorString = QString(); - qWarning("DirectShowPlayerService::doRender: Unresolved error code 0x%x (%s)", - uint(renderHr), qPrintable(comError(renderHr))); - } - } - - QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error))); - } - - m_executedTasks |= Render; - } -} - -void DirectShowPlayerService::doFinalizeLoad(QMutexLocker<QMutex> *locker) -{ - if (m_graphStatus != Loaded) { - if (IMediaEvent *event = com_cast<IMediaEvent>(m_graph, IID_IMediaEvent)) { - event->GetEventHandle(reinterpret_cast<OAEVENT *>(&m_eventHandle)); - event->Release(); - } - if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) { - LONGLONG duration = 0; - seeking->GetDuration(&duration); - m_duration = duration / qt_directShowTimeScale; - - DWORD capabilities = 0; - seeking->GetCapabilities(&capabilities); - m_seekable = capabilities & AM_SEEKING_CanSeekAbsolute; - - seeking->Release(); - } - } - - if ((m_executedTasks & SetOutputs) == SetOutputs) { - m_streamTypes = AudioStream | VideoStream; - } else { - m_streamTypes = findStreamTypes(m_source); - } - - m_executedTasks |= FinalizeLoad; - - m_graphStatus = Loaded; - - // Do not block gui thread while updating metadata from file. - locker->unlock(); - DirectShowMetaDataControl::updateMetadata(m_url.toString(), m_metadata); - locker->relock(); - - QCoreApplication::postEvent(this, new QEvent(QEvent::Type(FinalizedLoad))); -} - -void DirectShowPlayerService::releaseGraph() -{ - if (m_videoProbeControl) - m_videoProbeControl->flushVideoFrame(); - - if (m_graph) { - if (m_executingTask != 0) { - // {8E1C39A1-DE53-11cf-AA63-0080C744528D} - static const GUID iid_IAMOpenProgress = { - 0x8E1C39A1, 0xDE53, 0x11cf, {0xAA, 0x63, 0x00, 0x80, 0xC7, 0x44, 0x52, 0x8D} }; - - if (IAMOpenProgress *progress = com_cast<IAMOpenProgress>( - m_graph, iid_IAMOpenProgress)) { - progress->AbortOperation(); - progress->Release(); - } - m_graph->Abort(); - } - - m_pendingTasks = ReleaseGraph; - - ::SetEvent(m_taskHandle); - - m_loop->wait(&m_mutex); - DirectShowUtils::CoUninitializeIfNeeded(); - } -} - -void DirectShowPlayerService::doReleaseGraph(QMutexLocker<QMutex> *locker) -{ - Q_UNUSED(locker); - - if (IMediaControl *control = com_cast<IMediaControl>(m_graph, IID_IMediaControl)) { - control->Stop(); - control->Release(); - } - - doReleaseAudioProbe(locker); - doReleaseVideoProbe(locker); - - if (m_source) { - m_source->Release(); - m_source = nullptr; - } - - m_eventHandle = nullptr; - - m_graph->Release(); - m_graph = nullptr; - - if (m_graphBuilder) { - m_graphBuilder->Release(); - m_graphBuilder = nullptr; - } - - m_loop->wake(); -} - -QT_WARNING_PUSH -QT_WARNING_DISABLE_GCC("-Wmissing-field-initializers") - -void DirectShowPlayerService::doSetVideoProbe(QMutexLocker<QMutex> *locker) -{ - Q_UNUSED(locker); - - if (!m_graph || !m_graphBuilder) { - qCWarning(qtDirectShowPlugin, "Attempting to set a video probe without a valid graph!"); - return; - } - - // Create the sample grabber, if necessary. - if (!m_videoSampleGrabber) { - m_videoSampleGrabber = new DirectShowSampleGrabber; - connect(m_videoSampleGrabber, &DirectShowSampleGrabber::bufferAvailable, this, &DirectShowPlayerService::onVideoBufferAvailable); - } - - if (FAILED(m_graph->AddFilter(m_videoSampleGrabber->filter(), L"Video Sample Grabber"))) { - qCWarning(qtDirectShowPlugin, "Failed to add the video sample grabber into the graph!"); - return; - } - - DirectShowMediaType mediaType({ MEDIATYPE_Video, MEDIASUBTYPE_ARGB32 }); - m_videoSampleGrabber->setMediaType(&mediaType); - - // Connect source filter to sample grabber filter. - HRESULT hr = m_graphBuilder->RenderStream(nullptr, &MEDIATYPE_Video, - m_source, nullptr, m_videoSampleGrabber->filter()); - if (FAILED(hr)) { - qCWarning(qtDirectShowPlugin, "[0x%x] Failed to connect the video sample grabber", hr); - return; - } - - m_videoSampleGrabber->start(DirectShowSampleGrabber::CallbackMethod::BufferCB); -} - -void DirectShowPlayerService::doSetAudioProbe(QMutexLocker<QMutex> *locker) -{ - Q_UNUSED(locker); - - if (!m_graph) { - qCWarning(qtDirectShowPlugin, "Attempting to set an audio probe without a valid graph!"); - return; - } - - // Create the sample grabber, if necessary. - if (!m_audioSampleGrabber) { - m_audioSampleGrabber = new DirectShowSampleGrabber; - connect(m_audioSampleGrabber, &DirectShowSampleGrabber::bufferAvailable, this, &DirectShowPlayerService::onAudioBufferAvailable); - } - - static const AM_MEDIA_TYPE mediaType { MEDIATYPE_Audio, MEDIASUBTYPE_PCM }; - m_audioSampleGrabber->setMediaType(&mediaType); - - if (FAILED(m_graph->AddFilter(m_audioSampleGrabber->filter(), L"Audio Sample Grabber"))) { - qCWarning(qtDirectShowPlugin, "Failed to add the audio sample grabber into the graph!"); - return; - } - - if (!DirectShowUtils::connectFilters(m_graph, m_source, m_audioSampleGrabber->filter(), true)) { - // Connect source filter to sample grabber filter. - HRESULT hr = m_graphBuilder - ? m_graphBuilder->RenderStream(nullptr, &MEDIATYPE_Audio, - m_source, nullptr, m_audioSampleGrabber->filter()) - : E_FAIL; - if (FAILED(hr)) { - qCWarning(qtDirectShowPlugin, "[0x%x] Failed to connect the audio sample grabber", hr); - return; - } - } - - m_audioSampleGrabber->start(DirectShowSampleGrabber::CallbackMethod::BufferCB); -} - -QT_WARNING_POP - -void DirectShowPlayerService::doReleaseVideoProbe(QMutexLocker<QMutex> *locker) -{ - Q_UNUSED(locker); - - if (!m_graph) - return; - - if (!m_videoSampleGrabber) - return; - - m_videoSampleGrabber->stop(); - HRESULT hr = m_graph->RemoveFilter(m_videoSampleGrabber->filter()); - if (FAILED(hr)) { - qCWarning(qtDirectShowPlugin, "Failed to remove the video sample grabber!"); - return; - } - - m_videoSampleGrabber->deleteLater(); - m_videoSampleGrabber = nullptr; -} - -void DirectShowPlayerService::doReleaseAudioProbe(QMutexLocker<QMutex> *locker) -{ - Q_UNUSED(locker); - - if (!m_graph) - return; - - if (!m_audioSampleGrabber) - return; - - m_audioSampleGrabber->stop(); - HRESULT hr = m_graph->RemoveFilter(m_audioSampleGrabber->filter()); - if (FAILED(hr)) { - qCWarning(qtDirectShowPlugin, "Failed to remove the audio sample grabber!"); - return; - } - - m_audioSampleGrabber->deleteLater(); - m_audioSampleGrabber = nullptr; -} - -int DirectShowPlayerService::findStreamTypes(IBaseFilter *source) const -{ - QVarLengthArray<IBaseFilter *, 16> filters; - source->AddRef(); - filters.append(source); - - int streamTypes = 0; - - while (!filters.isEmpty()) { - IEnumPins *pins = nullptr; - IBaseFilter *filter = filters[filters.size() - 1]; - filters.removeLast(); - - if (SUCCEEDED(filter->EnumPins(&pins))) { - for (IPin *pin = nullptr; pins->Next(1, &pin, nullptr) == S_OK; pin->Release()) { - PIN_DIRECTION direction; - if (pin->QueryDirection(&direction) == S_OK && direction == PINDIR_OUTPUT) { - DirectShowMediaType connectionType; - if (SUCCEEDED(pin->ConnectionMediaType(&connectionType))) { - IPin *peer = nullptr; - - if (connectionType->majortype == MEDIATYPE_Audio) { - streamTypes |= AudioStream; - } else if (connectionType->majortype == MEDIATYPE_Video) { - streamTypes |= VideoStream; - } else if (SUCCEEDED(pin->ConnectedTo(&peer))) { - PIN_INFO peerInfo; - if (SUCCEEDED(peer->QueryPinInfo(&peerInfo))) - filters.append(peerInfo.pFilter); - peer->Release(); - } - } else { - streamTypes |= findStreamType(pin); - } - } - } - pins->Release(); - } - filter->Release(); - } - return streamTypes; -} - -int DirectShowPlayerService::findStreamType(IPin *pin) const -{ - IEnumMediaTypes *types; - - if (SUCCEEDED(pin->EnumMediaTypes(&types))) { - bool video = false; - bool audio = false; - bool other = false; - - for (AM_MEDIA_TYPE *type = nullptr; - types->Next(1, &type, nullptr) == S_OK; - DirectShowMediaType::deleteType(type)) { - if (type->majortype == MEDIATYPE_Audio) - audio = true; - else if (type->majortype == MEDIATYPE_Video) - video = true; - else - other = true; - } - types->Release(); - - if (other) - return 0; - else if (audio && !video) - return AudioStream; - else if (!audio && video) - return VideoStream; - else - return 0; - } else { - return 0; - } -} - -void DirectShowPlayerService::play() -{ - QMutexLocker locker(&m_mutex); - - m_pendingTasks &= ~Pause; - m_pendingTasks |= Play; - - if (m_executedTasks & Render) { - if (m_executedTasks & Stop) { - m_atEnd = false; - if (m_seekPosition == -1) { - m_dontCacheNextSeekResult = true; - m_seekPosition = 0; - m_position = 0; - m_pendingTasks |= Seek; - } - m_executedTasks ^= Stop; - } - - ::SetEvent(m_taskHandle); - } - - updateStatus(); -} - -void DirectShowPlayerService::doPlay(QMutexLocker<QMutex> *locker) -{ - // Invalidate if there is an error while loading. - if (m_error != QMediaPlayer::NoError) { - m_graphStatus = InvalidMedia; - if (!m_errorString.isEmpty()) - qWarning("%s", qPrintable(m_errorString)); - m_errorString = QString(); - QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error))); - return; - } - - if (IMediaControl *control = com_cast<IMediaControl>(m_graph, IID_IMediaControl)) { - locker->unlock(); - HRESULT hr = control->Run(); - locker->relock(); - - control->Release(); - - if (SUCCEEDED(hr)) { - m_executedTasks |= Play; - - QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StatusChange))); - } else { - m_error = QMediaPlayer::ResourceError; - m_errorString = QString(); - qWarning("DirectShowPlayerService::doPlay: Unresolved error code 0x%x (%s)", - uint(hr), qPrintable(comError(hr))); - - QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error))); - } - } -} - -void DirectShowPlayerService::pause() -{ - QMutexLocker locker(&m_mutex); - - m_pendingTasks &= ~Play; - m_pendingTasks |= Pause; - - if (m_executedTasks & Render) { - if (m_executedTasks & Stop) { - if (m_seekPosition == -1) { - m_dontCacheNextSeekResult = true; - m_seekPosition = 0; - m_position = 0; - m_pendingTasks |= Seek; - } - m_executedTasks ^= Stop; - } - - ::SetEvent(m_taskHandle); - } - - updateStatus(); -} - -void DirectShowPlayerService::doPause(QMutexLocker<QMutex> *locker) -{ - if (IMediaControl *control = com_cast<IMediaControl>(m_graph, IID_IMediaControl)) { - locker->unlock(); - HRESULT hr = control->Pause(); - locker->relock(); - - control->Release(); - - if (SUCCEEDED(hr)) { - IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking); - if (!m_atEnd && seeking) { - LONGLONG position = 0; - - seeking->GetCurrentPosition(&position); - seeking->Release(); - - m_position = position / qt_directShowTimeScale; - } else { - m_position = 0; - m_atEnd = false; - } - - m_executedTasks |= Pause; - - QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StatusChange))); - } else { - m_error = QMediaPlayer::ResourceError; - m_errorString = QString(); - qWarning("DirectShowPlayerService::doPause: Unresolved error code 0x%x (%s)", - uint(hr), qPrintable(comError(hr))); - - QCoreApplication::postEvent(this, new QEvent(QEvent::Type(Error))); - } - } -} - -void DirectShowPlayerService::stop() -{ - QMutexLocker locker(&m_mutex); - - m_pendingTasks &= ~(Play | Pause | Seek); - - if ((m_executingTask | m_executedTasks) & (Play | Pause | Seek)) { - m_pendingTasks |= Stop; - if (m_videoProbeControl) - m_videoProbeControl->flushVideoFrame(); - - ::SetEvent(m_taskHandle); - - m_loop->wait(&m_mutex); - } - - updateStatus(); -} - -void DirectShowPlayerService::doStop(QMutexLocker<QMutex> *locker) -{ - Q_UNUSED(locker); - if (m_executedTasks & (Play | Pause)) { - if (IMediaControl *control = com_cast<IMediaControl>(m_graph, IID_IMediaControl)) { - control->Stop(); - control->Release(); - } - - m_seekPosition = 0; - m_position = 0; - m_dontCacheNextSeekResult = true; - m_pendingTasks |= Seek; - - m_executedTasks &= ~(Play | Pause); - - QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StatusChange))); - } - - m_executedTasks |= Stop; - - m_loop->wake(); -} - -void DirectShowPlayerService::setRate(qreal rate) -{ - QMutexLocker locker(&m_mutex); - - m_rate = rate; - - m_pendingTasks |= SetRate; - - if (m_executedTasks & FinalizeLoad) - ::SetEvent(m_taskHandle); -} - -void DirectShowPlayerService::doSetRate(QMutexLocker<QMutex> *locker) -{ - if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) { - // Cache current values as we can't query IMediaSeeking during a seek due to the - // possibility of a deadlock when flushing the VideoSurfaceFilter. - LONGLONG currentPosition = 0; - seeking->GetCurrentPosition(¤tPosition); - m_position = currentPosition / qt_directShowTimeScale; - - LONGLONG minimum = 0; - LONGLONG maximum = 0; - m_playbackRange = SUCCEEDED(seeking->GetAvailable(&minimum, &maximum)) - ? QMediaTimeRange(minimum / qt_directShowTimeScale, maximum / qt_directShowTimeScale) - : QMediaTimeRange(); - - locker->unlock(); - HRESULT hr = seeking->SetRate(m_rate); - locker->relock(); - - if (!SUCCEEDED(hr)) { - qWarning("%s: Audio device or filter does not support rate: %.2f. " \ - "Falling back to previous value.", __FUNCTION__, m_rate); - - double rate = 0.0; - m_rate = SUCCEEDED(seeking->GetRate(&rate)) - ? rate - : 1.0; - } - - seeking->Release(); - } else if (m_rate != 1.0) { - m_rate = 1.0; - } - QCoreApplication::postEvent(this, new QEvent(QEvent::Type(RateChange))); -} - -qint64 DirectShowPlayerService::position() const -{ - QMutexLocker locker(const_cast<QMutex *>(&m_mutex)); - - if (m_graphStatus == Loaded) { - if (m_executingTask == Seek || m_executingTask == SetRate || (m_pendingTasks & Seek)) - return m_position; - if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) { - LONGLONG position = 0; - - seeking->GetCurrentPosition(&position); - seeking->Release(); - - const_cast<qint64 &>(m_position) = position / qt_directShowTimeScale; - - return m_position; - } - } - return 0; -} - -QMediaTimeRange DirectShowPlayerService::availablePlaybackRanges() const -{ - QMutexLocker locker(const_cast<QMutex *>(&m_mutex)); - - if (m_graphStatus == Loaded) { - if (m_executingTask == Seek || m_executingTask == SetRate || (m_pendingTasks & Seek)) - return m_playbackRange; - if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) { - LONGLONG minimum = 0; - LONGLONG maximum = 0; - - HRESULT hr = seeking->GetAvailable(&minimum, &maximum); - seeking->Release(); - - if (SUCCEEDED(hr)) - return QMediaTimeRange(minimum, maximum); - } - } - return QMediaTimeRange(); -} - -void DirectShowPlayerService::seek(qint64 position) -{ - QMutexLocker locker(&m_mutex); - - m_seekPosition = position; - - m_pendingTasks |= Seek; - - if (m_executedTasks & FinalizeLoad) - ::SetEvent(m_taskHandle); -} - -void DirectShowPlayerService::doSeek(QMutexLocker<QMutex> *locker) -{ - if (m_seekPosition == -1) - return; - - if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) { - LONGLONG seekPosition = LONGLONG(m_seekPosition) * qt_directShowTimeScale; - - // Cache current values as we can't query IMediaSeeking during a seek due to the - // possibility of a deadlock when flushing the VideoSurfaceFilter. - LONGLONG currentPosition = 0; - if (!m_dontCacheNextSeekResult) { - seeking->GetCurrentPosition(¤tPosition); - m_position = currentPosition / qt_directShowTimeScale; - } - - LONGLONG minimum = 0; - LONGLONG maximum = 0; - m_playbackRange = SUCCEEDED(seeking->GetAvailable(&minimum, &maximum)) - ? QMediaTimeRange( - minimum / qt_directShowTimeScale, maximum / qt_directShowTimeScale) - : QMediaTimeRange(); - - locker->unlock(); - seeking->SetPositions( - &seekPosition, AM_SEEKING_AbsolutePositioning, nullptr, AM_SEEKING_NoPositioning); - locker->relock(); - - if (!m_dontCacheNextSeekResult) { - seeking->GetCurrentPosition(¤tPosition); - m_position = currentPosition / qt_directShowTimeScale; - } - - seeking->Release(); - - QCoreApplication::postEvent(this, new QEvent(QEvent::Type(PositionChange))); - } - - m_seekPosition = -1; - m_dontCacheNextSeekResult = false; -} - -int DirectShowPlayerService::bufferStatus() const -{ -#if QT_CONFIG(wmsdk) - QMutexLocker locker(const_cast<QMutex *>(&m_mutex)); - - if (IWMReaderAdvanced2 *reader = com_cast<IWMReaderAdvanced2>( - m_source, IID_IWMReaderAdvanced2)) { - DWORD percentage = 0; - - reader->GetBufferProgress(&percentage, nullptr); - reader->Release(); - - return percentage; - } - return 0; -#else - return 0; -#endif -} - -void DirectShowPlayerService::setAudioOutput(IBaseFilter *filter) -{ - QMutexLocker locker(&m_mutex); - - if (m_graph) { - if (m_audioOutput) { - if (m_executedTasks & SetAudioOutput) { - m_pendingTasks |= ReleaseAudioOutput; - - ::SetEvent(m_taskHandle); - - m_loop->wait(&m_mutex); - } - m_audioOutput->Release(); - } - - m_audioOutput = filter; - - if (m_audioOutput) { - m_audioOutput->AddRef(); - - m_pendingTasks |= SetAudioOutput; - - if (m_executedTasks & SetSource) { - m_pendingTasks |= Render; - - ::SetEvent(m_taskHandle); - } - } else { - m_pendingTasks &= ~ SetAudioOutput; - } - } else { - if (m_audioOutput) - m_audioOutput->Release(); - - m_audioOutput = filter; - - if (m_audioOutput) - m_audioOutput->AddRef(); - } - - m_playerControl->updateAudioOutput(m_audioOutput); -} - -void DirectShowPlayerService::doReleaseAudioOutput(QMutexLocker<QMutex> *locker) -{ - Q_UNUSED(locker); - m_pendingTasks |= m_executedTasks & (Play | Pause); - - if (IMediaControl *control = com_cast<IMediaControl>(m_graph, IID_IMediaControl)) { - control->Stop(); - control->Release(); - } - - IBaseFilter *decoder = getConnected(m_audioOutput, PINDIR_INPUT); - if (!decoder) { - decoder = m_audioOutput; - decoder->AddRef(); - } - - // {DCFBDCF6-0DC2-45f5-9AB2-7C330EA09C29} - static const GUID iid_IFilterChain = { - 0xDCFBDCF6, 0x0DC2, 0x45f5, {0x9A, 0xB2, 0x7C, 0x33, 0x0E, 0xA0, 0x9C, 0x29} }; - - if (IFilterChain *chain = com_cast<IFilterChain>(m_graph, iid_IFilterChain)) { - chain->RemoveChain(decoder, m_audioOutput); - chain->Release(); - } else { - m_graph->RemoveFilter(m_audioOutput); - } - - decoder->Release(); - - m_executedTasks &= ~SetAudioOutput; - - m_loop->wake(); -} - -void DirectShowPlayerService::setVideoOutput(IBaseFilter *filter) -{ - QMutexLocker locker(&m_mutex); - - if (m_graph) { - if (m_videoOutput) { - if (m_executedTasks & SetVideoOutput) { - m_pendingTasks |= ReleaseVideoOutput; - - ::SetEvent(m_taskHandle); - - m_loop->wait(&m_mutex); - } - m_videoOutput->Release(); - } - - m_videoOutput = filter; - - if (m_videoOutput) { - m_videoOutput->AddRef(); - - m_pendingTasks |= SetVideoOutput; - - if (m_executedTasks & SetSource) { - m_pendingTasks |= Render; - - ::SetEvent(m_taskHandle); - } - } - } else { - if (m_videoOutput) - m_videoOutput->Release(); - - m_videoOutput = filter; - - if (m_videoOutput) - m_videoOutput->AddRef(); - } -} - -void DirectShowPlayerService::updateAudioProbe() -{ - QMutexLocker locker(&m_mutex); - - // Set/Activate the audio probe. - if (m_graph) { - // If we don't have a audio probe, then stop and release the audio sample grabber - if (!m_audioProbeControl && (m_executedTasks & SetAudioProbe)) { - m_pendingTasks |= ReleaseAudioProbe; - ::SetEvent(m_taskHandle); - m_loop->wait(&m_mutex); - } else if (m_audioProbeControl) { - m_pendingTasks |= SetAudioProbe; - } - } -} - -void DirectShowPlayerService::updateVideoProbe() -{ - QMutexLocker locker(&m_mutex); - - // Set/Activate the video probe. - if (m_graph) { - // If we don't have a video probe, then stop and release the video sample grabber - if (!m_videoProbeControl && (m_executedTasks & SetVideoProbe)) { - m_pendingTasks |= ReleaseVideoProbe; - ::SetEvent(m_taskHandle); - m_loop->wait(&m_mutex); - } else if (m_videoProbeControl){ - m_pendingTasks |= SetVideoProbe; - } - } -} - -void DirectShowPlayerService::doReleaseVideoOutput(QMutexLocker<QMutex> *locker) -{ - Q_UNUSED(locker); - m_pendingTasks |= m_executedTasks & (Play | Pause); - - if (IMediaControl *control = com_cast<IMediaControl>(m_graph, IID_IMediaControl)) { - control->Stop(); - control->Release(); - } - - IBaseFilter *intermediate = nullptr; - if (!SUCCEEDED(m_graph->FindFilterByName(L"Color Space Converter", &intermediate))) { - intermediate = m_videoOutput; - intermediate->AddRef(); - } - - IBaseFilter *decoder = getConnected(intermediate, PINDIR_INPUT); - if (!decoder) { - decoder = intermediate; - decoder->AddRef(); - } - - // {DCFBDCF6-0DC2-45f5-9AB2-7C330EA09C29} - static const GUID iid_IFilterChain = { - 0xDCFBDCF6, 0x0DC2, 0x45f5, {0x9A, 0xB2, 0x7C, 0x33, 0x0E, 0xA0, 0x9C, 0x29} }; - - if (IFilterChain *chain = com_cast<IFilterChain>(m_graph, iid_IFilterChain)) { - chain->RemoveChain(decoder, m_videoOutput); - chain->Release(); - } else { - m_graph->RemoveFilter(m_videoOutput); - } - - intermediate->Release(); - decoder->Release(); - - m_executedTasks &= ~SetVideoOutput; - - m_loop->wake(); -} - -void DirectShowPlayerService::customEvent(QEvent *event) -{ - if (event->type() == QEvent::Type(FinalizedLoad)) { - QMutexLocker locker(&m_mutex); - - m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable); - if (m_metadata.isEmpty()) - DirectShowMetaDataControl::updateMetadata(m_graph, m_source, m_metadata); - - m_metaDataControl->setMetadata(m_metadata); - m_metadata.clear(); - - updateStatus(); - } else if (event->type() == QEvent::Type(Error)) { - QMutexLocker locker(&m_mutex); - - if (m_error != QMediaPlayer::NoError) { - m_playerControl->updateError(m_error, m_errorString); - m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable); - m_playerControl->updateState(QMediaPlayer::StoppedState); - updateStatus(); - } - } else if (event->type() == QEvent::Type(RateChange)) { - QMutexLocker locker(&m_mutex); - - m_playerControl->updatePlaybackRate(m_rate); - } else if (event->type() == QEvent::Type(StatusChange)) { - QMutexLocker locker(&m_mutex); - - updateStatus(); - m_playerControl->updatePosition(m_position); - } else if (event->type() == QEvent::Type(DurationChange)) { - QMutexLocker locker(&m_mutex); - - m_playerControl->updateMediaInfo(m_duration, m_streamTypes, m_seekable); - } else if (event->type() == QEvent::Type(EndOfMedia)) { - QMutexLocker locker(&m_mutex); - - if (m_atEnd) { - m_playerControl->updateState(QMediaPlayer::StoppedState); - m_playerControl->updateStatus(QMediaPlayer::EndOfMedia); - m_playerControl->updatePosition(m_position); - if (m_videoProbeControl) - m_videoProbeControl->flushVideoFrame(); - } - } else if (event->type() == QEvent::Type(PositionChange)) { - QMutexLocker locker(&m_mutex); - - if (m_playerControl->mediaStatus() == QMediaPlayer::EndOfMedia) - m_playerControl->updateStatus(QMediaPlayer::LoadedMedia); - m_playerControl->updatePosition(m_position); - // Emits only when seek has been performed. - if (m_videoRendererControl) - emit m_videoRendererControl->positionChanged(m_position); - } else { - QMediaService::customEvent(event); - } -} - -void DirectShowPlayerService::videoOutputChanged() -{ - setVideoOutput(m_videoRendererControl->filter()); -} - -QT_WARNING_PUSH -QT_WARNING_DISABLE_GCC("-Wmissing-field-initializers") - -void DirectShowPlayerService::onAudioBufferAvailable(double time, const QByteArray &data) -{ - QMutexLocker locker(&m_mutex); - if (!m_audioProbeControl || !m_audioSampleGrabber) - return; - - DirectShowMediaType mt(AM_MEDIA_TYPE { GUID_NULL }); - const bool ok = m_audioSampleGrabber->getConnectedMediaType(&mt); - if (!ok) - return; - - if (mt->majortype != MEDIATYPE_Audio) - return; - - if (mt->subtype != MEDIASUBTYPE_PCM) - return; - - const bool isWfx = ((mt->formattype == FORMAT_WaveFormatEx) && (mt->cbFormat >= sizeof(WAVEFORMATEX))); - WAVEFORMATEX *wfx = isWfx ? reinterpret_cast<WAVEFORMATEX *>(mt->pbFormat) : nullptr; - - if (!wfx) - return; - - if (wfx->wFormatTag != WAVE_FORMAT_PCM && wfx->wFormatTag != WAVE_FORMAT_EXTENSIBLE) - return; - - if ((wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) && (wfx->cbSize >= sizeof(WAVEFORMATEXTENSIBLE))) { - WAVEFORMATEXTENSIBLE *wfxe = reinterpret_cast<WAVEFORMATEXTENSIBLE *>(wfx); - if (wfxe->SubFormat != KSDATAFORMAT_SUBTYPE_PCM) - return; - } - - QAudioFormat format; - format.setSampleRate(wfx->nSamplesPerSec); - format.setChannelCount(wfx->nChannels); - format.setSampleSize(wfx->wBitsPerSample); - format.setCodec("audio/pcm"); - format.setByteOrder(QAudioFormat::LittleEndian); - if (format.sampleSize() == 8) - format.setSampleType(QAudioFormat::UnSignedInt); - else - format.setSampleType(QAudioFormat::SignedInt); - - const quint64 startTime = quint64(time * 1000.); - QAudioBuffer audioBuffer(data, - format, - startTime); - - Q_EMIT m_audioProbeControl->audioBufferProbed(audioBuffer); -} - -void DirectShowPlayerService::onVideoBufferAvailable(double time, const QByteArray &data) -{ - Q_UNUSED(time); - - QMutexLocker locker(&m_mutex); - if (!m_videoProbeControl || !m_videoSampleGrabber) - return; - - DirectShowMediaType mt(AM_MEDIA_TYPE { GUID_NULL }); - const bool ok = m_videoSampleGrabber->getConnectedMediaType(&mt); - if (!ok) - return; - - if (mt->majortype != MEDIATYPE_Video) - return; - - QVideoFrame::PixelFormat format = DirectShowMediaType::pixelFormatFromType(&mt); - if (format == QVideoFrame::Format_Invalid) { - qCWarning(qtDirectShowPlugin, "Invalid format, stopping video probes!"); - m_videoSampleGrabber->stop(); - return; - } - - const QVideoSurfaceFormat &videoFormat = DirectShowMediaType::videoFormatFromType(&mt); - if (!videoFormat.isValid()) - return; - - const QSize &size = videoFormat.frameSize(); - - const int bytesPerLine = DirectShowMediaType::bytesPerLine(videoFormat); - QVideoFrame frame(new QMemoryVideoBuffer(data, bytesPerLine), - size, - format); - - m_videoProbeControl->probeVideoFrame(frame); -} - -QT_WARNING_POP - -void DirectShowPlayerService::graphEvent(QMutexLocker<QMutex> *locker) -{ - Q_UNUSED(locker); - if (IMediaEvent *event = com_cast<IMediaEvent>(m_graph, IID_IMediaEvent)) { - long eventCode; - LONG_PTR param1; - LONG_PTR param2; - - while (event->GetEvent(&eventCode, ¶m1, ¶m2, 0) == S_OK) { - switch (eventCode) { - case EC_BUFFERING_DATA: - m_buffering = param1; - - QCoreApplication::postEvent(this, new QEvent(QEvent::Type(StatusChange))); - break; - case EC_COMPLETE: - m_executedTasks &= ~(Play | Pause); - m_executedTasks |= Stop; - - m_buffering = false; - m_atEnd = true; - - if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) { - LONGLONG position = 0; - - seeking->GetCurrentPosition(&position); - seeking->Release(); - - m_position = position / qt_directShowTimeScale; - } - - QCoreApplication::postEvent(this, new QEvent(QEvent::Type(EndOfMedia))); - break; - case EC_LENGTH_CHANGED: - if (IMediaSeeking *seeking = com_cast<IMediaSeeking>(m_graph, IID_IMediaSeeking)) { - LONGLONG duration = 0; - seeking->GetDuration(&duration); - m_duration = duration / qt_directShowTimeScale; - - DWORD capabilities = 0; - seeking->GetCapabilities(&capabilities); - m_seekable = capabilities & AM_SEEKING_CanSeekAbsolute; - - seeking->Release(); - - QCoreApplication::postEvent(this, new QEvent(QEvent::Type(DurationChange))); - } - break; - default: - break; - } - - event->FreeEventParams(eventCode, param1, param2); - } - event->Release(); - } -} - -void DirectShowPlayerService::updateStatus() -{ - switch (m_graphStatus) { - case NoMedia: - m_playerControl->updateStatus(QMediaPlayer::NoMedia); - break; - case Loading: - m_playerControl->updateStatus(QMediaPlayer::LoadingMedia); - break; - case Loaded: - if ((m_executingTask | m_executedTasks) & (Play | Pause)) { - if (m_buffering) - m_playerControl->updateStatus(QMediaPlayer::BufferingMedia); - else - m_playerControl->updateStatus(QMediaPlayer::BufferedMedia); - } else { - m_playerControl->updateStatus(QMediaPlayer::LoadedMedia); - } - break; - case InvalidMedia: - m_playerControl->updateStatus(QMediaPlayer::InvalidMedia); - break; - default: - m_playerControl->updateStatus(QMediaPlayer::UnknownMediaStatus); - } -} - -bool DirectShowPlayerService::isConnected(IBaseFilter *filter, PIN_DIRECTION direction) const -{ - bool connected = false; - - IEnumPins *pins = nullptr; - - if (SUCCEEDED(filter->EnumPins(&pins))) { - for (IPin *pin = nullptr; pins->Next(1, &pin, nullptr) == S_OK; pin->Release()) { - PIN_DIRECTION dir; - if (SUCCEEDED(pin->QueryDirection(&dir)) && dir == direction) { - IPin *peer = nullptr; - if (SUCCEEDED(pin->ConnectedTo(&peer))) { - connected = true; - - peer->Release(); - } - } - } - pins->Release(); - } - return connected; -} - -IBaseFilter *DirectShowPlayerService::getConnected( - IBaseFilter *filter, PIN_DIRECTION direction) const -{ - IBaseFilter *connected = nullptr; - - IEnumPins *pins = nullptr; - - if (SUCCEEDED(filter->EnumPins(&pins))) { - for (IPin *pin = nullptr; pins->Next(1, &pin, nullptr) == S_OK; pin->Release()) { - PIN_DIRECTION dir; - if (SUCCEEDED(pin->QueryDirection(&dir)) && dir == direction) { - IPin *peer = nullptr; - if (SUCCEEDED(pin->ConnectedTo(&peer))) { - PIN_INFO info; - - if (SUCCEEDED(peer->QueryPinInfo(&info))) { - if (connected) { - qWarning("DirectShowPlayerService::getConnected: " - "Multiple connected filters"); - connected->Release(); - } - connected = info.pFilter; - } - peer->Release(); - } - } - } - pins->Release(); - } - return connected; -} - -void DirectShowPlayerService::run() -{ - QMutexLocker locker(&m_mutex); - - for (;;) { - while (m_pendingTasks == 0) { - DWORD result = 0; - - locker.unlock(); - if (m_eventHandle) { - HANDLE handles[] = { m_taskHandle, m_eventHandle }; - - result = ::WaitForMultipleObjects(2, handles, false, INFINITE); - } else { - result = ::WaitForSingleObject(m_taskHandle, INFINITE); - } - locker.relock(); - - if (result == WAIT_OBJECT_0 + 1) { - graphEvent(&locker); - } - } - - if (m_pendingTasks & ReleaseGraph) { - m_pendingTasks ^= ReleaseGraph; - m_executingTask = ReleaseGraph; - - doReleaseGraph(&locker); - //if the graph is released, we should not process other operations later - if (m_pendingTasks & Shutdown) { - m_pendingTasks = 0; - return; - } - m_pendingTasks = 0; - } else if (m_pendingTasks & Shutdown) { - return; - } else if (m_pendingTasks & ReleaseAudioOutput) { - m_pendingTasks ^= ReleaseAudioOutput; - m_executingTask = ReleaseAudioOutput; - - doReleaseAudioOutput(&locker); - } else if (m_pendingTasks & ReleaseVideoOutput) { - m_pendingTasks ^= ReleaseVideoOutput; - m_executingTask = ReleaseVideoOutput; - - doReleaseVideoOutput(&locker); - } else if (m_pendingTasks & ReleaseAudioProbe) { - m_pendingTasks ^= ReleaseAudioProbe; - m_executingTask = ReleaseAudioProbe; - - doReleaseAudioProbe(&locker); - } else if (m_pendingTasks & ReleaseVideoProbe) { - m_pendingTasks ^= ReleaseVideoProbe; - m_executingTask = ReleaseVideoProbe; - - doReleaseVideoProbe(&locker); - } else if (m_pendingTasks & SetUrlSource) { - m_pendingTasks ^= SetUrlSource; - m_executingTask = SetUrlSource; - - doSetUrlSource(&locker); - } else if (m_pendingTasks & SetStreamSource) { - m_pendingTasks ^= SetStreamSource; - m_executingTask = SetStreamSource; - - doSetStreamSource(&locker); - } else if (m_pendingTasks & SetAudioProbe) { - m_pendingTasks ^= SetAudioProbe; - m_executingTask = SetAudioProbe; - - doSetAudioProbe(&locker); - } else if (m_pendingTasks & SetVideoProbe) { - m_pendingTasks ^= SetVideoProbe; - m_executingTask = SetVideoProbe; - - doSetVideoProbe(&locker); - } else if (m_pendingTasks & Render) { - m_pendingTasks ^= Render; - m_executingTask = Render; - - doRender(&locker); - } else if (!(m_executedTasks & Render)) { - m_pendingTasks &= ~(FinalizeLoad | SetRate | Stop | Pause | Seek | Play); - } else if (m_pendingTasks & FinalizeLoad) { - m_pendingTasks ^= FinalizeLoad; - m_executingTask = FinalizeLoad; - - doFinalizeLoad(&locker); - } else if (m_pendingTasks & Stop) { - m_pendingTasks ^= Stop; - m_executingTask = Stop; - - doStop(&locker); - } else if (m_pendingTasks & SetRate) { - m_pendingTasks ^= SetRate; - m_executingTask = SetRate; - - doSetRate(&locker); - } else if (m_pendingTasks & Pause) { - m_pendingTasks ^= Pause; - m_executingTask = Pause; - - doPause(&locker); - } else if (m_pendingTasks & Seek) { - m_pendingTasks ^= Seek; - m_executingTask = Seek; - - doSeek(&locker); - } else if (m_pendingTasks & Play) { - m_pendingTasks ^= Play; - m_executingTask = Play; - - doPlay(&locker); - } - m_executingTask = 0; - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/player/directshowplayerservice.h b/src/plugins/directshow/player/directshowplayerservice.h deleted file mode 100644 index 9631a2a70..000000000 --- a/src/plugins/directshow/player/directshowplayerservice.h +++ /dev/null @@ -1,240 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWPLAYERSERVICE_H -#define DIRECTSHOWPLAYERSERVICE_H - -#include <dshow.h> - -#include "qmediaplayer.h" -#include "qmediaservice.h" -#include "qmediatimerange.h" - -#include "directshoweventloop.h" -#include "directshowglobal.h" - -#include <QtCore/qcoreevent.h> -#include <QtCore/qmutex.h> -#include <QtCore/qurl.h> -#include <QtCore/qwaitcondition.h> - -QT_BEGIN_NAMESPACE - -class DirectShowAudioEndpointControl; -class DirectShowMetaDataControl; -class DirectShowPlayerControl; -class DirectShowVideoRendererControl; -class DirectShowAudioProbeControl; -class DirectShowVideoProbeControl; -class DirectShowSampleGrabber; - -class QMediaContent; -class QVideoWindowControl; - -class DirectShowPlayerService : public QMediaService -{ - Q_OBJECT -public: - enum StreamType - { - AudioStream = 0x01, - VideoStream = 0x02 - }; - - DirectShowPlayerService(QObject *parent = nullptr); - ~DirectShowPlayerService() override; - - QMediaControl *requestControl(const char *name) override; - void releaseControl(QMediaControl *control) override; - - void load(const QMediaContent &media, QIODevice *stream); - void play(); - void pause(); - void stop(); - - qint64 position() const; - QMediaTimeRange availablePlaybackRanges() const; - - void seek(qint64 position); - void setRate(qreal rate); - - int bufferStatus() const; - - void setAudioOutput(IBaseFilter *filter); - void setVideoOutput(IBaseFilter *filter); - -protected: - void customEvent(QEvent *event) override; - -private Q_SLOTS: - void videoOutputChanged(); - - void onAudioBufferAvailable(double time, const QByteArray &data); - void onVideoBufferAvailable(double time, const QByteArray &data); - -private: - void releaseGraph(); - void updateStatus(); - - void updateAudioProbe(); - void updateVideoProbe(); - - int findStreamTypes(IBaseFilter *source) const; - int findStreamType(IPin *pin) const; - - bool isConnected(IBaseFilter *filter, PIN_DIRECTION direction) const; - IBaseFilter *getConnected(IBaseFilter *filter, PIN_DIRECTION direction) const; - - void run(); - - void doSetUrlSource(QMutexLocker<QMutex> *locker); - void doSetStreamSource(QMutexLocker<QMutex> *locker); - void doRender(QMutexLocker<QMutex> *locker); - void doFinalizeLoad(QMutexLocker<QMutex> *locker); - void doSetRate(QMutexLocker<QMutex> *locker); - void doSeek(QMutexLocker<QMutex> *locker); - void doPlay(QMutexLocker<QMutex> *locker); - void doPause(QMutexLocker<QMutex> *locker); - void doStop(QMutexLocker<QMutex> *locker); - void doReleaseAudioOutput(QMutexLocker<QMutex> *locker); - void doReleaseVideoOutput(QMutexLocker<QMutex> *locker); - void doReleaseGraph(QMutexLocker<QMutex> *locker); - void doSetVideoProbe(QMutexLocker<QMutex> *locker); - void doSetAudioProbe(QMutexLocker<QMutex> *locker); - void doReleaseVideoProbe(QMutexLocker<QMutex> *locker); - void doReleaseAudioProbe(QMutexLocker<QMutex> *locker); - - void graphEvent(QMutexLocker<QMutex> *locker); - - enum Task - { - Shutdown = 0x00001, - SetUrlSource = 0x00002, - SetStreamSource = 0x00004, - SetSource = SetUrlSource | SetStreamSource, - SetAudioOutput = 0x00008, - SetVideoOutput = 0x00010, - SetOutputs = SetAudioOutput | SetVideoOutput, - SetAudioProbe = 0x00020, - SetVideoProbe = 0x00040, - SetProbes = SetAudioProbe | SetVideoProbe, - Render = 0x00080, - FinalizeLoad = 0x00100, - SetRate = 0x00200, - Seek = 0x00400, - Play = 0x00800, - Pause = 0x01000, - Stop = 0x02000, - ReleaseGraph = 0x04000, - ReleaseAudioOutput = 0x08000, - ReleaseVideoOutput = 0x10000, - ReleaseAudioProbe = 0x20000, - ReleaseVideoProbe = 0x40000, - ReleaseFilters = ReleaseGraph | ReleaseAudioOutput - | ReleaseVideoOutput | ReleaseAudioProbe - | ReleaseVideoProbe - }; - - enum Event - { - FinalizedLoad = QEvent::User, - Error, - RateChange, - Started, - Paused, - DurationChange, - StatusChange, - EndOfMedia, - PositionChange - }; - - enum GraphStatus - { - NoMedia, - Loading, - Loaded, - InvalidMedia - }; - - DirectShowPlayerControl *m_playerControl = nullptr; - DirectShowMetaDataControl *m_metaDataControl = nullptr; - DirectShowVideoRendererControl *m_videoRendererControl = nullptr; - QVideoWindowControl *m_videoWindowControl = nullptr; - DirectShowAudioEndpointControl *m_audioEndpointControl = nullptr; - DirectShowAudioProbeControl *m_audioProbeControl = nullptr; - DirectShowVideoProbeControl *m_videoProbeControl = nullptr; - DirectShowSampleGrabber *m_audioSampleGrabber = nullptr; - DirectShowSampleGrabber *m_videoSampleGrabber = nullptr; - - QThread *m_taskThread = nullptr; - DirectShowEventLoop *m_loop; - int m_pendingTasks = 0; - int m_executingTask = 0; - int m_executedTasks = 0; - int m_streamTypes = 0; - HANDLE m_taskHandle; - HANDLE m_eventHandle = nullptr; - GraphStatus m_graphStatus = NoMedia; - QMediaPlayer::Error m_error = QMediaPlayer::NoError; - QIODevice *m_stream = nullptr; - IFilterGraph2 *m_graph = nullptr; - ICaptureGraphBuilder2 *m_graphBuilder = nullptr; - IBaseFilter *m_source = nullptr; - IBaseFilter *m_audioOutput = nullptr; - IBaseFilter *m_videoOutput = nullptr; - qreal m_rate = 1; - qint64 m_position = 0; - qint64 m_seekPosition = -1; - qint64 m_duration = 0; - QMediaTimeRange m_playbackRange; - QUrl m_url; - QString m_errorString; - QMutex m_mutex; - bool m_buffering = false; - bool m_seekable = false; - bool m_atEnd = false; - bool m_dontCacheNextSeekResult = false; - QVariantMap m_metadata; - - friend class DirectShowPlayerServiceThread; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/directshow/player/directshowvideorenderercontrol.cpp b/src/plugins/directshow/player/directshowvideorenderercontrol.cpp deleted file mode 100644 index 0b1f0de2f..000000000 --- a/src/plugins/directshow/player/directshowvideorenderercontrol.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QtMultimedia/private/qtmultimediaglobal_p.h> -#include "directshowvideorenderercontrol.h" - -#include "videosurfacefilter.h" - -#if QT_CONFIG(evr) -#include "evrcustompresenter.h" -#endif - -#include <qabstractvideosurface.h> - -DirectShowVideoRendererControl::DirectShowVideoRendererControl(DirectShowEventLoop *loop, QObject *parent) - : QVideoRendererControl(parent) - , m_loop(loop) -{ -} - -DirectShowVideoRendererControl::~DirectShowVideoRendererControl() -{ -#if QT_CONFIG(evr) - if (m_evrPresenter) { - m_evrPresenter->setSurface(nullptr); - m_evrPresenter->Release(); - } -#endif - if (m_filter) - m_filter->Release(); -} - -QAbstractVideoSurface *DirectShowVideoRendererControl::surface() const -{ - return m_surface; -} - -void DirectShowVideoRendererControl::setSurface(QAbstractVideoSurface *surface) -{ - if (m_surface == surface) - return; - -#if QT_CONFIG(evr) - if (m_evrPresenter) { - m_evrPresenter->setSurface(nullptr); - m_evrPresenter->Release(); - m_evrPresenter = nullptr; - } -#endif - - if (m_filter) { - m_filter->Release(); - m_filter = nullptr; - } - - m_surface = surface; - - if (m_surface) { -#if QT_CONFIG(evr) - if (!qgetenv("QT_DIRECTSHOW_NO_EVR").toInt()) { - m_filter = com_new<IBaseFilter>(clsid_EnhancedVideoRenderer); - m_evrPresenter = new EVRCustomPresenter(m_surface); - connect(this, &DirectShowVideoRendererControl::positionChanged, m_evrPresenter, &EVRCustomPresenter::positionChanged); - if (!m_evrPresenter->isValid() || !qt_evr_setCustomPresenter(m_filter, m_evrPresenter)) { - m_filter->Release(); - m_filter = nullptr; - m_evrPresenter->Release(); - m_evrPresenter = nullptr; - } - } - - if (!m_filter) -#endif - { - m_filter = new VideoSurfaceFilter(m_surface, m_loop); - } - } - - emit filterChanged(); -} - -IBaseFilter *DirectShowVideoRendererControl::filter() -{ - return m_filter; -} diff --git a/src/plugins/directshow/player/directshowvideorenderercontrol.h b/src/plugins/directshow/player/directshowvideorenderercontrol.h deleted file mode 100644 index 9326a2748..000000000 --- a/src/plugins/directshow/player/directshowvideorenderercontrol.h +++ /dev/null @@ -1,84 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWVIDEORENDERERCONTROL_H -#define DIRECTSHOWVIDEORENDERERCONTROL_H - -#include <QtMultimedia/private/qtmultimediaglobal_p.h> -#include <dshow.h> - -#include "qvideorenderercontrol.h" - -#include <QtMultimedia/private/qtmultimedia-config_p.h> - -QT_BEGIN_NAMESPACE - -class DirectShowEventLoop; -#if QT_CONFIG(evr) -class EVRCustomPresenter; -#endif - -class DirectShowVideoRendererControl : public QVideoRendererControl -{ - Q_OBJECT -public: - DirectShowVideoRendererControl(DirectShowEventLoop *loop, QObject *parent = nullptr); - ~DirectShowVideoRendererControl() override; - - QAbstractVideoSurface *surface() const override; - void setSurface(QAbstractVideoSurface *surface) override; - - IBaseFilter *filter(); - -Q_SIGNALS: - void filterChanged(); - void positionChanged(qint64 position); - -private: - DirectShowEventLoop *m_loop; - QAbstractVideoSurface *m_surface = nullptr; - IBaseFilter *m_filter = nullptr; -#if QT_CONFIG(evr) - EVRCustomPresenter *m_evrPresenter = nullptr; -#endif -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/directshow/player/player.pri b/src/plugins/directshow/player/player.pri deleted file mode 100644 index ec1066db7..000000000 --- a/src/plugins/directshow/player/player.pri +++ /dev/null @@ -1,45 +0,0 @@ -INCLUDEPATH += $$PWD - -QMAKE_USE += directshow -LIBS += -lgdi32 - -mingw: LIBS_PRIVATE += -lksuser - -qtHaveModule(widgets): QT += widgets - -HEADERS += \ - $$PWD/directshowioreader.h \ - $$PWD/directshowiosource.h \ - $$PWD/directshowplayercontrol.h \ - $$PWD/directshowplayerservice.h \ - $$PWD/directshowvideorenderercontrol.h \ - $$PWD/videosurfacefilter.h \ - $$PWD/directshowaudioendpointcontrol.h \ - $$PWD/directshowmetadatacontrol.h \ - $$PWD/vmr9videowindowcontrol.h - -SOURCES += \ - $$PWD/directshowioreader.cpp \ - $$PWD/directshowiosource.cpp \ - $$PWD/directshowplayercontrol.cpp \ - $$PWD/directshowplayerservice.cpp \ - $$PWD/directshowvideorenderercontrol.cpp \ - $$PWD/videosurfacefilter.cpp \ - $$PWD/directshowaudioendpointcontrol.cpp \ - $$PWD/directshowmetadatacontrol.cpp \ - $$PWD/vmr9videowindowcontrol.cpp - -qtConfig(evr) { - include($$PWD/../../common/evr.pri) - - HEADERS += \ - $$PWD/directshowevrvideowindowcontrol.h - - SOURCES += \ - $$PWD/directshowevrvideowindowcontrol.cpp -} else { - LIBS += -lwinmm -} - -qtConfig(wshellitem): \ - QT += core-private diff --git a/src/plugins/directshow/player/videosurfacefilter.cpp b/src/plugins/directshow/player/videosurfacefilter.cpp deleted file mode 100644 index 4b7afc266..000000000 --- a/src/plugins/directshow/player/videosurfacefilter.cpp +++ /dev/null @@ -1,810 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "videosurfacefilter.h" - -#include "directshoweventloop.h" -#include "directshowglobal.h" -#include "directshowvideobuffer.h" - -#include <QtCore/qthread.h> -#include <QtCore/qloggingcategory.h> -#include <qabstractvideosurface.h> - -#include <mutex> - -#include <initguid.h> - -QT_BEGIN_NAMESPACE - -Q_LOGGING_CATEGORY(qLcRenderFilter, "qt.multimedia.plugins.directshow.renderfilter") - -// { e23cad72-153d-406c-bf3f-4c4b523d96f2 } -DEFINE_GUID(CLSID_VideoSurfaceFilter, -0xe23cad72, 0x153d, 0x406c, 0xbf, 0x3f, 0x4c, 0x4b, 0x52, 0x3d, 0x96, 0xf2); - -class VideoSurfaceInputPin : public DirectShowInputPin -{ - COM_REF_MIXIN -public: - VideoSurfaceInputPin(VideoSurfaceFilter *filter); - - STDMETHODIMP QueryInterface(REFIID riid, void **ppv) override; - - bool isMediaTypeSupported(const AM_MEDIA_TYPE *type) override; - bool setMediaType(const AM_MEDIA_TYPE *type) override; - - HRESULT completeConnection(IPin *pin) override; - HRESULT connectionEnded() override; - - // IPin - STDMETHODIMP ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt) override; - STDMETHODIMP Disconnect() override; - STDMETHODIMP EndOfStream() override; - STDMETHODIMP BeginFlush() override; - STDMETHODIMP EndFlush() override; - - // IMemInputPin - STDMETHODIMP GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps) override; - STDMETHODIMP Receive(IMediaSample *pMediaSample) override; - -private: - VideoSurfaceFilter *m_videoSurfaceFilter; -}; - -VideoSurfaceInputPin::VideoSurfaceInputPin(VideoSurfaceFilter *filter) - : DirectShowInputPin(filter, QStringLiteral("Input")) - , m_videoSurfaceFilter(filter) -{ -} - -HRESULT VideoSurfaceInputPin::QueryInterface(REFIID riid, void **ppv) -{ - if (ppv == nullptr) - return E_POINTER; - if (riid == IID_IUnknown) - *ppv = static_cast<IUnknown *>(static_cast<DirectShowPin *>(this)); - else if (riid == IID_IPin) - *ppv = static_cast<IPin *>(this); - else if (riid == IID_IMemInputPin) - *ppv =static_cast<IMemInputPin*>(this); - else - return E_NOINTERFACE; - AddRef(); - return S_OK; -} - -bool VideoSurfaceInputPin::isMediaTypeSupported(const AM_MEDIA_TYPE *type) -{ - return m_videoSurfaceFilter->isMediaTypeSupported(type); -} - -bool VideoSurfaceInputPin::setMediaType(const AM_MEDIA_TYPE *type) -{ - if (!DirectShowInputPin::setMediaType(type)) - return false; - - return m_videoSurfaceFilter->setMediaType(type); -} - -HRESULT VideoSurfaceInputPin::completeConnection(IPin *pin) -{ - HRESULT hr = DirectShowInputPin::completeConnection(pin); - if (FAILED(hr)) - return hr; - - return m_videoSurfaceFilter->completeConnection(pin); -} - -HRESULT VideoSurfaceInputPin::connectionEnded() -{ - HRESULT hr = DirectShowInputPin::connectionEnded(); - if (FAILED(hr)) - return hr; - - return m_videoSurfaceFilter->connectionEnded(); -} - -HRESULT VideoSurfaceInputPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt) -{ - QMutexLocker lock(&m_videoSurfaceFilter->m_mutex); - return DirectShowInputPin::ReceiveConnection(pConnector, pmt); -} - -HRESULT VideoSurfaceInputPin::Disconnect() -{ - QMutexLocker lock(&m_videoSurfaceFilter->m_mutex); - return DirectShowInputPin::Disconnect(); -} - -HRESULT VideoSurfaceInputPin::EndOfStream() -{ - QMutexLocker lock(&m_videoSurfaceFilter->m_mutex); - const std::lock_guard<QRecursiveMutex> renderLocker(m_videoSurfaceFilter->m_renderMutex); - - HRESULT hr = DirectShowInputPin::EndOfStream(); - if (hr != S_OK) - return hr; - - return m_videoSurfaceFilter->EndOfStream(); -} - -HRESULT VideoSurfaceInputPin::BeginFlush() -{ - QMutexLocker lock(&m_videoSurfaceFilter->m_mutex); - { - const std::lock_guard<QRecursiveMutex> renderLocker(m_videoSurfaceFilter->m_renderMutex); - DirectShowInputPin::BeginFlush(); - m_videoSurfaceFilter->BeginFlush(); - } - m_videoSurfaceFilter->resetEOS(); - - return S_OK; -} - -HRESULT VideoSurfaceInputPin::EndFlush() -{ - QMutexLocker lock(&m_videoSurfaceFilter->m_mutex); - const std::lock_guard<QRecursiveMutex> renderLocker(m_videoSurfaceFilter->m_renderMutex); - - HRESULT hr = m_videoSurfaceFilter->EndFlush(); - if (SUCCEEDED(hr)) - hr = DirectShowInputPin::EndFlush(); - return hr; -} - -HRESULT VideoSurfaceInputPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps) -{ - if (!pProps) - return E_POINTER; - - // We need at least two allocated buffers, one for holding the frame currently being - // rendered and another one to decode the following frame at the same time. - pProps->cBuffers = 2; - - return S_OK; -} - -HRESULT VideoSurfaceInputPin::Receive(IMediaSample *pMediaSample) -{ - HRESULT hr = m_videoSurfaceFilter->Receive(pMediaSample); - if (FAILED(hr)) { - QMutexLocker locker(&m_videoSurfaceFilter->m_mutex); - if (m_videoSurfaceFilter->state() != State_Stopped && !m_flushing && !m_inErrorState) { - m_videoSurfaceFilter->NotifyEvent(EC_ERRORABORT, hr, 0); - { - const std::lock_guard<QRecursiveMutex> renderLocker(m_videoSurfaceFilter->m_renderMutex); - if (m_videoSurfaceFilter->m_running && !m_videoSurfaceFilter->m_EOSDelivered) - m_videoSurfaceFilter->notifyEOS(); - } - m_inErrorState = true; - } - } - - return hr; -} - - -VideoSurfaceFilter::VideoSurfaceFilter(QAbstractVideoSurface *surface, DirectShowEventLoop *loop, QObject *parent) - : QObject(parent) - , m_loop(loop) - , m_surface(surface) - , m_renderEvent(CreateEvent(nullptr, FALSE, FALSE, nullptr)) - , m_flushEvent(CreateEvent(nullptr, TRUE, FALSE, nullptr)) -{ - supportedFormatsChanged(); - connect(surface, &QAbstractVideoSurface::supportedFormatsChanged, - this, &VideoSurfaceFilter::supportedFormatsChanged); -} - -VideoSurfaceFilter::~VideoSurfaceFilter() -{ - clearPendingSample(); - - if (m_pin) - m_pin->Release(); - - CloseHandle(m_flushEvent); - CloseHandle(m_renderEvent); -} - -HRESULT VideoSurfaceFilter::QueryInterface(REFIID riid, void **ppv) -{ - if (ppv == nullptr) - return E_POINTER; - if (riid == IID_IUnknown) - *ppv = static_cast<IUnknown *>(static_cast<DirectShowBaseFilter *>(this)); - else if (riid == IID_IPersist || riid == IID_IMediaFilter || riid == IID_IBaseFilter) - *ppv = static_cast<IBaseFilter *>(this); - else if (riid == IID_IAMFilterMiscFlags) - *ppv = static_cast<IAMFilterMiscFlags *>(this); - else - return E_NOINTERFACE; - AddRef(); - return S_OK; -} - -QList<DirectShowPin *> VideoSurfaceFilter::pins() -{ - if (!m_pin) - m_pin = new VideoSurfaceInputPin(this); - - return QList<DirectShowPin *>() << m_pin; -} - -HRESULT VideoSurfaceFilter::GetClassID(CLSID *pClassID) -{ - *pClassID = CLSID_VideoSurfaceFilter; - return S_OK; -} - -ULONG VideoSurfaceFilter::GetMiscFlags() -{ - return AM_FILTER_MISC_FLAGS_IS_RENDERER; -} - -void VideoSurfaceFilter::supportedFormatsChanged() -{ - QWriteLocker writeLocker(&m_typesLock); - - qCDebug(qLcRenderFilter, "supportedFormatChanged"); - - m_supportedTypes.clear(); - - const QList<QVideoFrame::PixelFormat> formats = m_surface->supportedPixelFormats(); - m_supportedTypes.reserve(formats.count()); - - for (QVideoFrame::PixelFormat format : formats) { - GUID subtype = DirectShowMediaType::convertPixelFormat(format); - if (!IsEqualGUID(subtype, MEDIASUBTYPE_None)) { - qCDebug(qLcRenderFilter) << " " << format; - m_supportedTypes.append(subtype); - } - } -} - -bool VideoSurfaceFilter::isMediaTypeSupported(const AM_MEDIA_TYPE *type) -{ - if (type->majortype != MEDIATYPE_Video || type->bFixedSizeSamples == FALSE) - return false; - - QReadLocker readLocker(&m_typesLock); - - for (const GUID &supportedType : m_supportedTypes) { - if (IsEqualGUID(supportedType, type->subtype)) - return true; - } - - return false; -} - -bool VideoSurfaceFilter::setMediaType(const AM_MEDIA_TYPE *type) -{ - if (!type) { - qCDebug(qLcRenderFilter, "clear media type"); - m_surfaceFormat = QVideoSurfaceFormat(); - m_bytesPerLine = 0; - return true; - } - m_surfaceFormat = DirectShowMediaType::videoFormatFromType(type); - m_bytesPerLine = DirectShowMediaType::bytesPerLine(m_surfaceFormat); - qCDebug(qLcRenderFilter) << "setMediaType -->" << m_surfaceFormat; - return m_surfaceFormat.isValid(); -} - -HRESULT VideoSurfaceFilter::completeConnection(IPin *pin) -{ - Q_UNUSED(pin); - - qCDebug(qLcRenderFilter, "completeConnection"); - - return startSurface() ? S_OK : VFW_E_TYPE_NOT_ACCEPTED; -} - -HRESULT VideoSurfaceFilter::connectionEnded() -{ - qCDebug(qLcRenderFilter, "connectionEnded"); - - stopSurface(); - - return S_OK; -} - -HRESULT VideoSurfaceFilter::Run(REFERENCE_TIME tStart) -{ - QMutexLocker locker(&m_mutex); - - if (m_state == State_Running) - return S_OK; - - qCDebug(qLcRenderFilter, "Run (start=%lli)", tStart); - - HRESULT hr = DirectShowBaseFilter::Run(tStart); - if (FAILED(hr)) - return hr; - - ResetEvent(m_flushEvent); - - IMemAllocator *allocator; - if (SUCCEEDED(m_pin->GetAllocator(&allocator))) { - allocator->Commit(); - allocator->Release(); - } - - const std::lock_guard<QRecursiveMutex> renderLocker(m_renderMutex); - - m_running = true; - - if (!m_pendingSample) - checkEOS(); - else if (!scheduleSample(m_pendingSample)) - SetEvent(m_renderEvent); // render immediately - - return S_OK; -} - -HRESULT VideoSurfaceFilter::Pause() -{ - QMutexLocker locker(&m_mutex); - - if (m_state == State_Paused) - return S_OK; - - qCDebug(qLcRenderFilter, "Pause"); - - HRESULT hr = DirectShowBaseFilter::Pause(); - if (FAILED(hr)) - return hr; - - m_renderMutex.lock(); - m_EOSDelivered = false; - m_running = false; - m_renderMutex.unlock(); - - resetEOSTimer(); - ResetEvent(m_flushEvent); - unscheduleSample(); - - IMemAllocator *allocator; - if (SUCCEEDED(m_pin->GetAllocator(&allocator))) { - allocator->Commit(); - allocator->Release(); - } - - return S_OK; -} - -HRESULT VideoSurfaceFilter::Stop() -{ - QMutexLocker locker(&m_mutex); - - if (m_state == State_Stopped) - return S_OK; - - qCDebug(qLcRenderFilter, "Stop"); - - DirectShowBaseFilter::Stop(); - - clearPendingSample(); - - m_renderMutex.lock(); - m_EOSDelivered = false; - m_running = false; - m_renderMutex.unlock(); - - SetEvent(m_flushEvent); - resetEOS(); - unscheduleSample(); - flushSurface(); - - IMemAllocator *allocator; - if (SUCCEEDED(m_pin->GetAllocator(&allocator))) { - allocator->Decommit(); - allocator->Release(); - } - - return S_OK; -} - -HRESULT VideoSurfaceFilter::EndOfStream() -{ - const std::lock_guard<QRecursiveMutex> renderLocker(m_renderMutex); - - qCDebug(qLcRenderFilter, "EndOfStream"); - - m_EOS = true; - - if (!m_pendingSample && m_running) - checkEOS(); - - stopSurface(); - return S_OK; -} - -HRESULT VideoSurfaceFilter::BeginFlush() -{ - qCDebug(qLcRenderFilter, "BeginFlush"); - - SetEvent(m_flushEvent); - unscheduleSample(); - clearPendingSample(); - - return S_OK; -} - -HRESULT VideoSurfaceFilter::EndFlush() -{ - qCDebug(qLcRenderFilter, "EndFlush"); - - ResetEvent(m_flushEvent); - return S_OK; -} - -HRESULT VideoSurfaceFilter::Receive(IMediaSample *pMediaSample) -{ - { - QMutexLocker locker(&m_mutex); - - qCDebug(qLcRenderFilter, "Receive (sample=%p)", pMediaSample); - - HRESULT hr = m_pin->DirectShowInputPin::Receive(pMediaSample); - if (hr != S_OK) { - qCDebug(qLcRenderFilter, " can't receive sample (error %X)", uint(hr)); - return E_FAIL; - } - - // If the format dynamically changed, the sample contains information about the new format. - // We need to reset the format and restart the QAbstractVideoSurface. - if (m_pin->currentSampleProperties()->pMediaType - && (!m_pin->setMediaType(m_pin->currentSampleProperties()->pMediaType) - || !restartSurface())) { - qCWarning(qLcRenderFilter, " dynamic format change failed, aborting rendering"); - NotifyEvent(EC_ERRORABORT, VFW_E_TYPE_NOT_ACCEPTED, 0); - return VFW_E_INVALIDMEDIATYPE; - } - - { - const std::lock_guard<QRecursiveMutex> locker(m_renderMutex); - - if (m_pendingSample || m_EOS) - return E_UNEXPECTED; - - if (m_running && !scheduleSample(pMediaSample)) { - qCWarning(qLcRenderFilter, " sample can't be scheduled, discarding it"); - return S_OK; - } - - m_pendingSample = pMediaSample; - m_pendingSample->AddRef(); - m_pendingSampleEndTime = m_pin->currentSampleProperties()->tStop; - } - - if (m_state == State_Paused) // Render immediately - renderPendingSample(); - } - - qCDebug(qLcRenderFilter, " waiting for render time"); - - // Wait for render time. The clock will wake us up whenever the time comes. - // It can also be interrupted by a flush, pause or stop. - HANDLE waitObjects[] = { m_flushEvent, m_renderEvent }; - DWORD result = WAIT_TIMEOUT; - while (result == WAIT_TIMEOUT) - result = WaitForMultipleObjects(2, waitObjects, FALSE, INFINITE); - - if (result == WAIT_OBJECT_0) { - // render interrupted (flush, pause, stop) - qCDebug(qLcRenderFilter, " rendering of sample %p interrupted", pMediaSample); - return S_OK; - } - - m_adviseCookie = 0; - - QMutexLocker locker(&m_mutex); - - // State might have changed just before the lock - if (m_state == State_Stopped) { - qCDebug(qLcRenderFilter, " state changed to Stopped, discarding sample (%p)", pMediaSample); - return S_OK; - } - - std::unique_lock<QRecursiveMutex> renderLocker(m_renderMutex); - - // Flush or pause might have happened just before the lock - if (m_pendingSample && m_running) { - renderLocker.unlock(); - renderPendingSample(); - renderLocker.lock(); - } else { - qCDebug(qLcRenderFilter, " discarding sample (%p)", pMediaSample); - } - - clearPendingSample(); - checkEOS(); - ResetEvent(m_renderEvent); - - return S_OK; -} - -bool VideoSurfaceFilter::scheduleSample(IMediaSample *sample) -{ - if (!sample) - return false; - - qCDebug(qLcRenderFilter, "scheduleSample (sample=%p)", sample); - - REFERENCE_TIME sampleStart, sampleEnd; - if (FAILED(sample->GetTime(&sampleStart, &sampleEnd)) || !m_clock) { - qCDebug(qLcRenderFilter, " render now"); - SetEvent(m_renderEvent); // Render immediately - return true; - } - - if (sampleEnd < sampleStart) { // incorrect times - qCWarning(qLcRenderFilter, " invalid sample times (start=%lli, end=%lli)", sampleStart, sampleEnd); - return false; - } - - HRESULT hr = m_clock->AdviseTime(m_startTime, sampleStart, (HEVENT)m_renderEvent, &m_adviseCookie); - if (FAILED(hr)) { - qCWarning(qLcRenderFilter, " clock failed to advise time (error=%X)", uint(hr)); - return false; - } - - return true; -} - -void VideoSurfaceFilter::unscheduleSample() -{ - if (m_adviseCookie) { - qCDebug(qLcRenderFilter, "unscheduleSample"); - m_clock->Unadvise(m_adviseCookie); - m_adviseCookie = 0; - } - - ResetEvent(m_renderEvent); -} - -void VideoSurfaceFilter::clearPendingSample() -{ - const std::lock_guard<QRecursiveMutex> locker(m_renderMutex); - if (m_pendingSample) { - qCDebug(qLcRenderFilter, "clearPendingSample"); - m_pendingSample->Release(); - m_pendingSample = nullptr; - } -} - -void QT_WIN_CALLBACK EOSTimerCallback(UINT, UINT, DWORD_PTR dwUser, DWORD_PTR, DWORD_PTR) -{ - VideoSurfaceFilter *that = reinterpret_cast<VideoSurfaceFilter *>(dwUser); - that->onEOSTimerTimeout(); -} - -void VideoSurfaceFilter::onEOSTimerTimeout() -{ - const std::lock_guard<QRecursiveMutex> locker(m_renderMutex); - - if (m_EOSTimer) { - m_EOSTimer = 0; - checkEOS(); - } -} - -void VideoSurfaceFilter::checkEOS() -{ - const std::lock_guard<QRecursiveMutex> locker(m_renderMutex); - - if (!m_EOS || m_EOSDelivered || m_EOSTimer) - return; - - if (!m_clock) { - notifyEOS(); - return; - } - - REFERENCE_TIME eosTime = m_startTime + m_pendingSampleEndTime; - REFERENCE_TIME currentTime; - m_clock->GetTime(¤tTime); - LONG delay = LONG((eosTime - currentTime) / 10000); - - if (delay < 1) { - notifyEOS(); - } else { - qCDebug(qLcRenderFilter, "will trigger EOS in %li", delay); - - m_EOSTimer = timeSetEvent(delay, - 1, - EOSTimerCallback, - reinterpret_cast<DWORD_PTR>(this), - TIME_ONESHOT | TIME_CALLBACK_FUNCTION | TIME_KILL_SYNCHRONOUS); - - if (!m_EOSTimer) { - qDebug("Error with timer"); - notifyEOS(); - } - } -} - -void VideoSurfaceFilter::notifyEOS() -{ - const std::lock_guard<QRecursiveMutex> locker(m_renderMutex); - - if (!m_running) - return; - - qCDebug(qLcRenderFilter, "notifyEOS, delivering EC_COMPLETE event"); - - m_EOSTimer = 0; - m_EOSDelivered = true; - NotifyEvent(EC_COMPLETE, S_OK, (LONG_PTR)(IBaseFilter *)this); -} - -void VideoSurfaceFilter::resetEOS() -{ - resetEOSTimer(); - - const std::lock_guard<QRecursiveMutex> locker(m_renderMutex); - - if (m_EOS) - qCDebug(qLcRenderFilter, "resetEOS (delivered=%s)", m_EOSDelivered ? "true" : "false"); - - m_EOS = false; - m_EOSDelivered = false; - m_pendingSampleEndTime = 0; -} - -void VideoSurfaceFilter::resetEOSTimer() -{ - if (m_EOSTimer) { - timeKillEvent(m_EOSTimer); - m_EOSTimer = 0; - } -} - -bool VideoSurfaceFilter::startSurface() -{ - if (QThread::currentThread() != thread()) { - m_loop->postEvent(this, new QEvent(QEvent::Type(StartSurface))); - m_waitSurface.wait(&m_mutex); - return m_surfaceStarted; - } - m_surfaceStarted = m_surface->start(m_surfaceFormat); - qCDebug(qLcRenderFilter, "startSurface %s", m_surfaceStarted ? "succeeded" : "failed"); - return m_surfaceStarted; -} - -void VideoSurfaceFilter::stopSurface() -{ - if (!m_surfaceStarted) - return; - - if (QThread::currentThread() != thread()) { - m_loop->postEvent(this, new QEvent(QEvent::Type(StopSurface))); - m_waitSurface.wait(&m_mutex); - } else { - qCDebug(qLcRenderFilter, "stopSurface"); - m_surface->stop(); - m_surfaceStarted = false; - } -} - -bool VideoSurfaceFilter::restartSurface() -{ - if (QThread::currentThread() != thread()) { - m_loop->postEvent(this, new QEvent(QEvent::Type(RestartSurface))); - m_waitSurface.wait(&m_mutex); - return m_surfaceStarted; - } - m_surface->stop(); - m_surfaceStarted = m_surface->start(m_surfaceFormat); - qCDebug(qLcRenderFilter, "restartSurface %s", m_surfaceStarted ? "succeeded" : "failed"); - return m_surfaceStarted; -} - -void VideoSurfaceFilter::flushSurface() -{ - if (QThread::currentThread() != thread()) { - m_loop->postEvent(this, new QEvent(QEvent::Type(FlushSurface))); - m_waitSurface.wait(&m_mutex); - } else { - qCDebug(qLcRenderFilter, "flushSurface"); - m_surface->present(QVideoFrame()); - } -} - -void VideoSurfaceFilter::renderPendingSample() -{ - if (QThread::currentThread() != thread()) { - m_loop->postEvent(this, new QEvent(QEvent::Type(RenderSample))); - m_waitSurface.wait(&m_mutex); - } else { - const std::lock_guard<QRecursiveMutex> locker(m_renderMutex); - if (!m_pendingSample) - return; - - qCDebug(qLcRenderFilter, "presentSample (sample=%p)", m_pendingSample); - - m_surface->present(QVideoFrame(new DirectShowVideoBuffer(m_pendingSample, m_bytesPerLine), - m_surfaceFormat.frameSize(), - m_surfaceFormat.pixelFormat())); - } -} - -bool VideoSurfaceFilter::event(QEvent *e) -{ - switch (e->type()) { - case StartSurface: { - QMutexLocker locker(&m_mutex); - startSurface(); - m_waitSurface.wakeAll(); - return true; - } - case StopSurface: { - QMutexLocker locker(&m_mutex); - stopSurface(); - m_waitSurface.wakeAll(); - return true; - } - case RestartSurface: { - QMutexLocker locker(&m_mutex); - restartSurface(); - m_waitSurface.wakeAll(); - return true; - } - case FlushSurface: { - QMutexLocker locker(&m_mutex); - flushSurface(); - m_waitSurface.wakeAll(); - return true; - } - case RenderSample: { - QMutexLocker locker(&m_mutex); - renderPendingSample(); - m_waitSurface.wakeAll(); - return true; - } - default: - break; - } - - return QObject::event(e); -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/player/videosurfacefilter.h b/src/plugins/directshow/player/videosurfacefilter.h deleted file mode 100644 index 9e56f4b65..000000000 --- a/src/plugins/directshow/player/videosurfacefilter.h +++ /dev/null @@ -1,161 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef VIDEOSURFACEFILTER_H -#define VIDEOSURFACEFILTER_H - -#include "directshowbasefilter.h" - -#include <QtCore/qcoreevent.h> -#include <QtCore/qmutex.h> -#include <qreadwritelock.h> -#include <qsemaphore.h> -#include <qwaitcondition.h> - -QT_BEGIN_NAMESPACE - -class QAbstractVideoSurface; - -class DirectShowEventLoop; -class VideoSurfaceInputPin; - -class VideoSurfaceFilter : public QObject - , public DirectShowBaseFilter - , public IAMFilterMiscFlags -{ - Q_OBJECT - COM_REF_MIXIN -public: - VideoSurfaceFilter(QAbstractVideoSurface *surface, DirectShowEventLoop *loop, QObject *parent = nullptr); - ~VideoSurfaceFilter(); - - STDMETHODIMP QueryInterface(REFIID riid, void **ppv) override; - - // DirectShowBaseFilter - QList<DirectShowPin *> pins() override; - - // IPersist - STDMETHODIMP GetClassID(CLSID *pClassID) override; - - // IMediaFilter - STDMETHODIMP Run(REFERENCE_TIME tStart) override; - STDMETHODIMP Pause() override; - STDMETHODIMP Stop() override; - - // IAMFilterMiscFlags - STDMETHODIMP_(ULONG) GetMiscFlags() override; - - // DirectShowPin (delegate) - bool isMediaTypeSupported(const AM_MEDIA_TYPE *type); - bool setMediaType(const AM_MEDIA_TYPE *type); - HRESULT completeConnection(IPin *pin); - HRESULT connectionEnded(); - - // IPin (delegate) - HRESULT EndOfStream(); - HRESULT BeginFlush(); - HRESULT EndFlush(); - - // IMemInputPin (delegate) - HRESULT Receive(IMediaSample *pMediaSample); - -private Q_SLOTS: - void supportedFormatsChanged(); - void checkEOS(); - -private: - enum Events { - StartSurface = QEvent::User, - StopSurface = QEvent::User + 1, - RestartSurface = QEvent::User + 2, - FlushSurface = QEvent::User + 3, - RenderSample = QEvent::User + 4 - }; - - bool event(QEvent *) override; - - bool startSurface(); - void stopSurface(); - bool restartSurface(); - void flushSurface(); - - bool scheduleSample(IMediaSample *sample); - void unscheduleSample(); - void renderPendingSample(); - void clearPendingSample(); - - void notifyEOS(); - void resetEOS(); - void resetEOSTimer(); - void onEOSTimerTimeout(); - - friend void QT_WIN_CALLBACK EOSTimerCallback(UINT, UINT, DWORD_PTR dwUser, DWORD_PTR, DWORD_PTR); - - QMutex m_mutex; - - DirectShowEventLoop *m_loop; - VideoSurfaceInputPin *m_pin = nullptr; - - QWaitCondition m_waitSurface; - QAbstractVideoSurface *m_surface; - QVideoSurfaceFormat m_surfaceFormat; - int m_bytesPerLine = 0; - bool m_surfaceStarted = false; - - QList<GUID> m_supportedTypes; - QReadWriteLock m_typesLock; - - QRecursiveMutex m_renderMutex; - bool m_running = false; - IMediaSample *m_pendingSample = nullptr; - REFERENCE_TIME m_pendingSampleEndTime = 0; - HANDLE m_renderEvent; - HANDLE m_flushEvent; - DWORD_PTR m_adviseCookie = 0; - - bool m_EOS = false; - bool m_EOSDelivered = false; - UINT m_EOSTimer = 0; - - friend class VideoSurfaceInputPin; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/directshow/player/vmr9videowindowcontrol.cpp b/src/plugins/directshow/player/vmr9videowindowcontrol.cpp deleted file mode 100644 index 63c945622..000000000 --- a/src/plugins/directshow/player/vmr9videowindowcontrol.cpp +++ /dev/null @@ -1,326 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "vmr9videowindowcontrol.h" - -#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)) -{ - if (IVMRFilterConfig9 *config = com_cast<IVMRFilterConfig9>(m_filter, IID_IVMRFilterConfig9)) { - config->SetRenderingMode(VMR9Mode_Windowless); - config->SetNumberOfStreams(1); - config->Release(); - } -} - -Vmr9VideoWindowControl::~Vmr9VideoWindowControl() -{ - if (m_filter) - m_filter->Release(); -} - - -WId Vmr9VideoWindowControl::winId() const -{ - return m_windowId; - -} - -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)) { - control->SetVideoClippingWindow(reinterpret_cast<HWND>(m_windowId)); - control->SetBorderColor(m_windowColor); - control->Release(); - } -} - -QRect Vmr9VideoWindowControl::displayRect() const -{ - return m_displayRect; -} - -void Vmr9VideoWindowControl::setDisplayRect(const QRect &rect) -{ - m_displayRect = rect; - - if (IVMRWindowlessControl9 *control = com_cast<IVMRWindowlessControl9>( - m_filter, IID_IVMRWindowlessControl9)) { - RECT sourceRect = { 0, 0, 0, 0 }; - RECT displayRect = { rect.left(), rect.top(), rect.right() + 1, rect.bottom() + 1 }; - - control->GetNativeVideoSize(&sourceRect.right, &sourceRect.bottom, nullptr, nullptr); - - if (m_aspectRatioMode == Qt::KeepAspectRatioByExpanding) { - QSize clippedSize = rect.size(); - clippedSize.scale(sourceRect.right, sourceRect.bottom, Qt::KeepAspectRatio); - - sourceRect.left = (sourceRect.right - clippedSize.width()) / 2; - sourceRect.top = (sourceRect.bottom - clippedSize.height()) / 2; - sourceRect.right = sourceRect.left + clippedSize.width(); - sourceRect.bottom = sourceRect.top + clippedSize.height(); - } - - control->SetVideoPosition(&sourceRect, &displayRect); - control->Release(); - } -} - -bool Vmr9VideoWindowControl::isFullScreen() const -{ - return m_fullScreen; -} - -void Vmr9VideoWindowControl::setFullScreen(bool fullScreen) -{ - emit fullScreenChanged(m_fullScreen = fullScreen); -} - -void Vmr9VideoWindowControl::repaint() -{ - PAINTSTRUCT paint; - - if (HDC dc = ::BeginPaint(reinterpret_cast<HWND>(m_windowId), &paint)) { - HRESULT hr = E_FAIL; - - if (IVMRWindowlessControl9 *control = com_cast<IVMRWindowlessControl9>( - m_filter, IID_IVMRWindowlessControl9)) { - hr = control->RepaintVideo(reinterpret_cast<HWND>(m_windowId), dc); - control->Release(); - } - - if (!SUCCEEDED(hr)) { - HPEN pen = ::CreatePen(PS_SOLID, 1, m_windowColor); - HBRUSH brush = ::CreateSolidBrush(m_windowColor); - ::SelectObject(dc, pen); - ::SelectObject(dc, brush); - - ::Rectangle( - dc, - m_displayRect.left(), - m_displayRect.top(), - m_displayRect.right() + 1, - m_displayRect.bottom() + 1); - - ::DeleteObject(pen); - ::DeleteObject(brush); - } - ::EndPaint(reinterpret_cast<HWND>(m_windowId), &paint); - } -} - -QSize Vmr9VideoWindowControl::nativeSize() const -{ - QSize size; - - if (IVMRWindowlessControl9 *control = com_cast<IVMRWindowlessControl9>( - m_filter, IID_IVMRWindowlessControl9)) { - LONG width; - LONG height; - - if (control->GetNativeVideoSize(&width, &height, nullptr, nullptr) == S_OK) - size = QSize(width, height); - control->Release(); - } - return size; -} - -Qt::AspectRatioMode Vmr9VideoWindowControl::aspectRatioMode() const -{ - return m_aspectRatioMode; -} - -void Vmr9VideoWindowControl::setAspectRatioMode(Qt::AspectRatioMode mode) -{ - m_aspectRatioMode = mode; - - if (IVMRWindowlessControl9 *control = com_cast<IVMRWindowlessControl9>( - m_filter, IID_IVMRWindowlessControl9)) { - switch (mode) { - case Qt::IgnoreAspectRatio: - control->SetAspectRatioMode(VMR9ARMode_None); - break; - case Qt::KeepAspectRatio: - control->SetAspectRatioMode(VMR9ARMode_LetterBox); - break; - case Qt::KeepAspectRatioByExpanding: - control->SetAspectRatioMode(VMR9ARMode_LetterBox); - setDisplayRect(m_displayRect); - break; - default: - break; - } - control->Release(); - } -} - -int Vmr9VideoWindowControl::brightness() const -{ - return m_brightness; -} - -void Vmr9VideoWindowControl::setBrightness(int brightness) -{ - m_brightness = brightness; - - m_dirtyValues |= ProcAmpControl9_Brightness; - - setProcAmpValues(); - - emit brightnessChanged(brightness); -} - -int Vmr9VideoWindowControl::contrast() const -{ - return m_contrast; -} - -void Vmr9VideoWindowControl::setContrast(int contrast) -{ - m_contrast = contrast; - - m_dirtyValues |= ProcAmpControl9_Contrast; - - setProcAmpValues(); - - emit contrastChanged(contrast); -} - -int Vmr9VideoWindowControl::hue() const -{ - return m_hue; -} - -void Vmr9VideoWindowControl::setHue(int hue) -{ - m_hue = hue; - - m_dirtyValues |= ProcAmpControl9_Hue; - - setProcAmpValues(); - - emit hueChanged(hue); -} - -int Vmr9VideoWindowControl::saturation() const -{ - return m_saturation; -} - -void Vmr9VideoWindowControl::setSaturation(int saturation) -{ - m_saturation = saturation; - - m_dirtyValues |= ProcAmpControl9_Saturation; - - setProcAmpValues(); - - emit saturationChanged(saturation); -} - -void Vmr9VideoWindowControl::setProcAmpValues() -{ - if (IVMRMixerControl9 *control = com_cast<IVMRMixerControl9>(m_filter, IID_IVMRMixerControl9)) { - VMR9ProcAmpControl procAmp; - procAmp.dwSize = sizeof(VMR9ProcAmpControl); - procAmp.dwFlags = m_dirtyValues; - - if (m_dirtyValues & ProcAmpControl9_Brightness) { - procAmp.Brightness = scaleProcAmpValue( - control, ProcAmpControl9_Brightness, m_brightness); - } - if (m_dirtyValues & ProcAmpControl9_Contrast) { - procAmp.Contrast = scaleProcAmpValue( - control, ProcAmpControl9_Contrast, m_contrast); - } - if (m_dirtyValues & ProcAmpControl9_Hue) { - procAmp.Hue = scaleProcAmpValue( - control, ProcAmpControl9_Hue, m_hue); - } - if (m_dirtyValues & ProcAmpControl9_Saturation) { - procAmp.Saturation = scaleProcAmpValue( - control, ProcAmpControl9_Saturation, m_saturation); - } - - if (SUCCEEDED(control->SetProcAmpControl(0, &procAmp))) { - m_dirtyValues = 0; - } - - control->Release(); - } -} - -float Vmr9VideoWindowControl::scaleProcAmpValue( - IVMRMixerControl9 *control, VMR9ProcAmpControlFlags property, int value) const -{ - float scaledValue = 0.0; - - VMR9ProcAmpControlRange range; - range.dwSize = sizeof(VMR9ProcAmpControlRange); - range.dwProperty = property; - - if (SUCCEEDED(control->GetProcAmpControlRange(0, &range))) { - scaledValue = range.DefaultValue; - if (value > 0) - scaledValue += float(value) * (range.MaxValue - range.DefaultValue) / 100; - else if (value < 0) - scaledValue -= float(value) * (range.MinValue - range.DefaultValue) / 100; - } - - return scaledValue; -} diff --git a/src/plugins/directshow/player/vmr9videowindowcontrol.h b/src/plugins/directshow/player/vmr9videowindowcontrol.h deleted file mode 100644 index 2a6f008f3..000000000 --- a/src/plugins/directshow/player/vmr9videowindowcontrol.h +++ /dev/null @@ -1,108 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef VMR9VIDEOWINDOWCONTROL_H -#define VMR9VIDEOWINDOWCONTROL_H - -#include "qvideowindowcontrol.h" - -#include <dshow.h> -#include <d3d9.h> -#include <vmr9.h> - -QT_BEGIN_NAMESPACE - -class Vmr9VideoWindowControl : public QVideoWindowControl -{ - Q_OBJECT -public: - Vmr9VideoWindowControl(QObject *parent = nullptr); - ~Vmr9VideoWindowControl() override; - - IBaseFilter *filter() const { return m_filter; } - - WId winId() const override; - void setWinId(WId id) override; - - QRect displayRect() const override; - void setDisplayRect(const QRect &rect) override; - - bool isFullScreen() const override; - void setFullScreen(bool fullScreen) override; - - void repaint() override; - - QSize nativeSize() const override; - - Qt::AspectRatioMode aspectRatioMode() const override; - void setAspectRatioMode(Qt::AspectRatioMode mode) override; - - int brightness() const override; - void setBrightness(int brightness) override; - - int contrast() const override; - void setContrast(int contrast) override; - - int hue() const override; - void setHue(int hue) override; - - int saturation() const override; - void setSaturation(int saturation) override; - -private: - void setProcAmpValues(); - float scaleProcAmpValue( - IVMRMixerControl9 *control, VMR9ProcAmpControlFlags property, int value) const; - - IBaseFilter *m_filter; - WId m_windowId = 0; - COLORREF m_windowColor = RGB(0, 0, 0); - DWORD m_dirtyValues = 0; - Qt::AspectRatioMode m_aspectRatioMode = Qt::KeepAspectRatio; - QRect m_displayRect; - int m_brightness = 0; - int m_contrast = 0; - int m_hue = 0; - int m_saturation = 0; - bool m_fullScreen = false; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/plugins.pro b/src/plugins/plugins.pro index 2af434ebb..f9cbfc8ec 100644 --- a/src/plugins/plugins.pro +++ b/src/plugins/plugins.pro @@ -23,7 +23,6 @@ qnx { win32: { SUBDIRS += audiocapture - qtConfig(directshow): SUBDIRS += directshow qtConfig(wmf): SUBDIRS += wmf } |