summaryrefslogtreecommitdiffstats
path: root/src/plugins/directshow/player
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/directshow/player')
-rw-r--r--src/plugins/directshow/player/directshowaudioendpointcontrol.cpp161
-rw-r--r--src/plugins/directshow/player/directshowaudioendpointcontrol.h82
-rw-r--r--src/plugins/directshow/player/directshowevrvideowindowcontrol.cpp66
-rw-r--r--src/plugins/directshow/player/directshowevrvideowindowcontrol.h63
-rw-r--r--src/plugins/directshow/player/directshowioreader.cpp462
-rw-r--r--src/plugins/directshow/player/directshowioreader.h120
-rw-r--r--src/plugins/directshow/player/directshowiosource.cpp530
-rw-r--r--src/plugins/directshow/player/directshowiosource.h140
-rw-r--r--src/plugins/directshow/player/directshowmetadatacontrol.cpp697
-rw-r--r--src/plugins/directshow/player/directshowmetadatacontrol.h84
-rw-r--r--src/plugins/directshow/player/directshowplayercontrol.cpp397
-rw-r--r--src/plugins/directshow/player/directshowplayercontrol.h153
-rw-r--r--src/plugins/directshow/player/directshowplayerservice.cpp1812
-rw-r--r--src/plugins/directshow/player/directshowplayerservice.h240
-rw-r--r--src/plugins/directshow/player/directshowvideorenderercontrol.cpp121
-rw-r--r--src/plugins/directshow/player/directshowvideorenderercontrol.h84
-rw-r--r--src/plugins/directshow/player/player.pri45
-rw-r--r--src/plugins/directshow/player/videosurfacefilter.cpp810
-rw-r--r--src/plugins/directshow/player/videosurfacefilter.h161
-rw-r--r--src/plugins/directshow/player/vmr9videowindowcontrol.cpp326
-rw-r--r--src/plugins/directshow/player/vmr9videowindowcontrol.h108
21 files changed, 0 insertions, 6662 deletions
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(&currentPosition);
- 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(&currentPosition);
- 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(&currentPosition);
- 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, &param1, &param2, 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(&currentTime);
- 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