diff options
Diffstat (limited to 'src/plugins/directshow')
78 files changed, 0 insertions, 14813 deletions
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 |