From c50fb7493753606cd436b08d33022f9b789dd2ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Str=C3=B8mme?= Date: Thu, 17 Nov 2016 17:51:48 +0100 Subject: DirectShow: Merge the helpers and common folder Change-Id: Ie1c39c26ae6dec288daafb24b5aa0b6cc2bdd218 Reviewed-by: Yoann Lopes --- src/plugins/directshow/common/common.pri | 19 + .../directshow/common/directshowbasefilter.cpp | 277 ++++++++ .../directshow/common/directshowbasefilter.h | 101 +++ .../directshow/common/directshoweventloop.cpp | 152 +++++ .../directshow/common/directshoweventloop.h | 80 +++ src/plugins/directshow/common/directshowglobal.h | 160 +++++ .../directshow/common/directshowmediatype.cpp | 350 ++++++++++ .../directshow/common/directshowmediatype.h | 97 +++ .../directshow/common/directshowmediatypeenum.cpp | 117 ++++ .../directshow/common/directshowmediatypeenum.h | 80 +++ src/plugins/directshow/common/directshowobject.cpp | 86 +++ src/plugins/directshow/common/directshowobject.h | 82 +++ src/plugins/directshow/common/directshowpin.cpp | 740 +++++++++++++++++++++ src/plugins/directshow/common/directshowpin.h | 192 ++++++ .../directshow/common/directshowpinenum.cpp | 130 ++++ src/plugins/directshow/common/directshowpinenum.h | 81 +++ src/plugins/directshow/common/directshowutils.cpp | 313 +++++++++ src/plugins/directshow/common/directshowutils.h | 87 +++ .../directshow/common/directshowvideobuffer.cpp | 88 +++ .../directshow/common/directshowvideobuffer.h | 70 ++ src/plugins/directshow/directshow.pro | 1 - .../directshow/helpers/directshowbasefilter.cpp | 277 -------- .../directshow/helpers/directshowbasefilter.h | 101 --- .../directshow/helpers/directshoweventloop.cpp | 152 ----- .../directshow/helpers/directshoweventloop.h | 80 --- src/plugins/directshow/helpers/directshowglobal.h | 160 ----- .../directshow/helpers/directshowmediatype.cpp | 350 ---------- .../directshow/helpers/directshowmediatype.h | 97 --- .../directshow/helpers/directshowmediatypeenum.cpp | 117 ---- .../directshow/helpers/directshowmediatypeenum.h | 80 --- .../directshow/helpers/directshowobject.cpp | 86 --- src/plugins/directshow/helpers/directshowobject.h | 82 --- src/plugins/directshow/helpers/directshowpin.cpp | 740 --------------------- src/plugins/directshow/helpers/directshowpin.h | 192 ------ .../directshow/helpers/directshowpinenum.cpp | 130 ---- src/plugins/directshow/helpers/directshowpinenum.h | 81 --- src/plugins/directshow/helpers/directshowutils.cpp | 313 --------- src/plugins/directshow/helpers/directshowutils.h | 87 --- .../directshow/helpers/directshowvideobuffer.cpp | 88 --- .../directshow/helpers/directshowvideobuffer.h | 70 -- src/plugins/directshow/helpers/helpers.pri | 24 - 41 files changed, 3302 insertions(+), 3308 deletions(-) create mode 100644 src/plugins/directshow/common/directshowbasefilter.cpp create mode 100644 src/plugins/directshow/common/directshowbasefilter.h create mode 100644 src/plugins/directshow/common/directshoweventloop.cpp create mode 100644 src/plugins/directshow/common/directshoweventloop.h create mode 100644 src/plugins/directshow/common/directshowglobal.h create mode 100644 src/plugins/directshow/common/directshowmediatype.cpp create mode 100644 src/plugins/directshow/common/directshowmediatype.h create mode 100644 src/plugins/directshow/common/directshowmediatypeenum.cpp create mode 100644 src/plugins/directshow/common/directshowmediatypeenum.h create mode 100644 src/plugins/directshow/common/directshowobject.cpp create mode 100644 src/plugins/directshow/common/directshowobject.h create mode 100644 src/plugins/directshow/common/directshowpin.cpp create mode 100644 src/plugins/directshow/common/directshowpin.h create mode 100644 src/plugins/directshow/common/directshowpinenum.cpp create mode 100644 src/plugins/directshow/common/directshowpinenum.h create mode 100644 src/plugins/directshow/common/directshowutils.cpp create mode 100644 src/plugins/directshow/common/directshowutils.h create mode 100644 src/plugins/directshow/common/directshowvideobuffer.cpp create mode 100644 src/plugins/directshow/common/directshowvideobuffer.h delete mode 100644 src/plugins/directshow/helpers/directshowbasefilter.cpp delete mode 100644 src/plugins/directshow/helpers/directshowbasefilter.h delete mode 100644 src/plugins/directshow/helpers/directshoweventloop.cpp delete mode 100644 src/plugins/directshow/helpers/directshoweventloop.h delete mode 100644 src/plugins/directshow/helpers/directshowglobal.h delete mode 100644 src/plugins/directshow/helpers/directshowmediatype.cpp delete mode 100644 src/plugins/directshow/helpers/directshowmediatype.h delete mode 100644 src/plugins/directshow/helpers/directshowmediatypeenum.cpp delete mode 100644 src/plugins/directshow/helpers/directshowmediatypeenum.h delete mode 100644 src/plugins/directshow/helpers/directshowobject.cpp delete mode 100644 src/plugins/directshow/helpers/directshowobject.h delete mode 100644 src/plugins/directshow/helpers/directshowpin.cpp delete mode 100644 src/plugins/directshow/helpers/directshowpin.h delete mode 100644 src/plugins/directshow/helpers/directshowpinenum.cpp delete mode 100644 src/plugins/directshow/helpers/directshowpinenum.h delete mode 100644 src/plugins/directshow/helpers/directshowutils.cpp delete mode 100644 src/plugins/directshow/helpers/directshowutils.h delete mode 100644 src/plugins/directshow/helpers/directshowvideobuffer.cpp delete mode 100644 src/plugins/directshow/helpers/directshowvideobuffer.h delete mode 100644 src/plugins/directshow/helpers/helpers.pri (limited to 'src') diff --git a/src/plugins/directshow/common/common.pri b/src/plugins/directshow/common/common.pri index 9b7c1e3f4..06f8582ac 100644 --- a/src/plugins/directshow/common/common.pri +++ b/src/plugins/directshow/common/common.pri @@ -1,11 +1,30 @@ INCLUDEPATH += $$PWD HEADERS += \ + $$PWD/directshowbasefilter.h \ + $$PWD/directshoweventloop.h \ + $$PWD/directshowglobal.h \ + $$PWD/directshowmediatype.h \ + $$PWD/directshowmediatypeenum.h \ + $$PWD/directshowobject.h \ + $$PWD/directshowpin.h \ + $$PWD/directshowpinenum.h \ + $$PWD/directshowvideobuffer.h \ + $$PWD/directshowutils.h \ $$PWD/directshowvideoprobecontrol.h \ $$PWD/directshowaudioprobecontrol.h \ $$PWD/directshowsamplegrabber.h SOURCES += \ + $$PWD/directshowbasefilter.cpp \ + $$PWD/directshoweventloop.cpp \ + $$PWD/directshowmediatype.cpp \ + $$PWD/directshowmediatypeenum.cpp \ + $$PWD/directshowobject.cpp \ + $$PWD/directshowpin.cpp \ + $$PWD/directshowpinenum.cpp \ + $$PWD/directshowvideobuffer.cpp \ + $$PWD/directshowutils.cpp \ $$PWD/directshowvideoprobecontrol.cpp \ $$PWD/directshowaudioprobecontrol.cpp \ $$PWD/directshowsamplegrabber.cpp diff --git a/src/plugins/directshow/common/directshowbasefilter.cpp b/src/plugins/directshow/common/directshowbasefilter.cpp new file mode 100644 index 000000000..342f0c271 --- /dev/null +++ b/src/plugins/directshow/common/directshowbasefilter.cpp @@ -0,0 +1,277 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "directshowbasefilter.h" + +#include "directshowpinenum.h" + +QT_BEGIN_NAMESPACE + +DirectShowBaseFilter::DirectShowBaseFilter() + : m_mutex(QMutex::Recursive) + , m_state(State_Stopped) + , m_graph(NULL) + , m_clock(NULL) + , m_sink(NULL) +{ + +} + +DirectShowBaseFilter::~DirectShowBaseFilter() +{ + if (m_clock) { + m_clock->Release(); + m_clock = NULL; + } +} + +HRESULT DirectShowBaseFilter::getInterface(REFIID riid, void **ppvObject) +{ + if (riid == IID_IPersist + || riid == IID_IMediaFilter + || riid == IID_IBaseFilter) { + return GetInterface(static_cast(this), ppvObject); + } else { + return DirectShowObject::getInterface(riid, ppvObject); + } +} + +HRESULT DirectShowBaseFilter::GetClassID(CLSID *pClassID) +{ + *pClassID = CLSID_NULL; + return S_OK; +} + +HRESULT DirectShowBaseFilter::NotifyEvent(long eventCode, LONG_PTR eventParam1, LONG_PTR eventParam2) +{ + IMediaEventSink *sink = m_sink; + if (sink) { + if (eventCode == EC_COMPLETE) + eventParam2 = (LONG_PTR)(IBaseFilter*)this; + + return sink->Notify(eventCode, eventParam1, eventParam2); + } else { + return E_NOTIMPL; + } +} + +HRESULT DirectShowBaseFilter::Run(REFERENCE_TIME tStart) +{ + Q_UNUSED(tStart) + QMutexLocker locker(&m_mutex); + + m_startTime = tStart; + + if (m_state == State_Stopped){ + HRESULT hr = Pause(); + if (FAILED(hr)) + return hr; + } + + m_state = State_Running; + + return S_OK; +} + +HRESULT DirectShowBaseFilter::Pause() +{ + QMutexLocker locker(&m_mutex); + + if (m_state == State_Stopped) { + const QList pinList = pins(); + for (DirectShowPin *pin : pinList) { + if (pin->isConnected()) { + HRESULT hr = pin->setActive(true); + if (FAILED(hr)) + return hr; + } + } + } + + m_state = State_Paused; + + return S_OK; +} + +HRESULT DirectShowBaseFilter::Stop() +{ + QMutexLocker locker(&m_mutex); + + HRESULT hr = S_OK; + + if (m_state != State_Stopped) { + const QList pinList = pins(); + for (DirectShowPin *pin : pinList) { + if (pin->isConnected()) { + HRESULT hrTmp = pin->setActive(false); + if (FAILED(hrTmp) && SUCCEEDED(hr)) + hr = hrTmp; + } + } + } + + m_state = State_Stopped; + + return hr; +} + +HRESULT DirectShowBaseFilter::GetState(DWORD dwMilliSecsTimeout, FILTER_STATE *pState) +{ + Q_UNUSED(dwMilliSecsTimeout); + + if (!pState) { + return E_POINTER; + } else { + QMutexLocker locker(&m_mutex); + + *pState = m_state; + + return S_OK; + } +} + +HRESULT DirectShowBaseFilter::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 DirectShowBaseFilter::GetSyncSource(IReferenceClock **ppClock) +{ + if (!ppClock) { + return E_POINTER; + } else { + if (!m_clock) { + *ppClock = 0; + + return S_FALSE; + } else { + m_clock->AddRef(); + + *ppClock = m_clock; + + return S_OK; + } + } +} + +HRESULT DirectShowBaseFilter::EnumPins(IEnumPins **ppEnum) +{ + if (!ppEnum) { + return E_POINTER; + } else { + *ppEnum = new DirectShowPinEnum(this); + return S_OK; + } +} + +HRESULT DirectShowBaseFilter::FindPin(LPCWSTR Id, IPin **ppPin) +{ + if (!ppPin || !Id) { + return E_POINTER; + } else { + QMutexLocker locker(&m_mutex); + const QList pinList = pins(); + for (DirectShowPin *pin : pinList) { + if (QString::fromWCharArray(Id) == pin->name()) { + pin->AddRef(); + *ppPin = pin; + return S_OK; + } + } + + *ppPin = 0; + return VFW_E_NOT_FOUND; + } +} + +HRESULT DirectShowBaseFilter::JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName) +{ + QMutexLocker locker(&m_mutex); + + m_filterName = QString::fromWCharArray(pName); + m_graph = pGraph; + m_sink = NULL; + + if (m_graph) { + if (SUCCEEDED(m_graph->QueryInterface(IID_PPV_ARGS(&m_sink)))) + m_sink->Release(); // we don't keep a reference on it + } + + return S_OK; +} + +HRESULT DirectShowBaseFilter::QueryFilterInfo(FILTER_INFO *pInfo) +{ + if (!pInfo) { + return E_POINTER; + } else { + QString name = m_filterName; + + if (name.length() >= MAX_FILTER_NAME) + name.truncate(MAX_FILTER_NAME - 1); + + int length = name.toWCharArray(pInfo->achName); + pInfo->achName[length] = '\0'; + + if (m_graph) + m_graph->AddRef(); + + pInfo->pGraph = m_graph; + + return S_OK; + } +} + +HRESULT DirectShowBaseFilter::QueryVendorInfo(LPWSTR *pVendorInfo) +{ + Q_UNUSED(pVendorInfo); + return E_NOTIMPL; +} + +QT_END_NAMESPACE diff --git a/src/plugins/directshow/common/directshowbasefilter.h b/src/plugins/directshow/common/directshowbasefilter.h new file mode 100644 index 000000000..9a2f44567 --- /dev/null +++ b/src/plugins/directshow/common/directshowbasefilter.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTSHOWBASEFILTER_H +#define DIRECTSHOWBASEFILTER_H + +#include "directshowpin.h" + +QT_BEGIN_NAMESPACE + +class DirectShowBaseFilter : public DirectShowObject + , public IBaseFilter +{ + DIRECTSHOW_OBJECT + +public: + DirectShowBaseFilter(); + virtual ~DirectShowBaseFilter(); + + FILTER_STATE state() const { return m_state; } + HRESULT NotifyEvent(long eventCode, LONG_PTR eventParam1, LONG_PTR eventParam2); + + virtual QList pins() = 0; + + // DirectShowObject + HRESULT getInterface(const IID &riid, void **ppvObject); + + // IPersist + STDMETHODIMP GetClassID(CLSID *pClassID); + + // IMediaFilter + STDMETHODIMP Run(REFERENCE_TIME tStart); + STDMETHODIMP Pause(); + STDMETHODIMP Stop(); + + STDMETHODIMP GetState(DWORD dwMilliSecsTimeout, FILTER_STATE *pState); + + STDMETHODIMP SetSyncSource(IReferenceClock *pClock); + STDMETHODIMP GetSyncSource(IReferenceClock **ppClock); + + // IBaseFilter + STDMETHODIMP EnumPins(IEnumPins **ppEnum); + STDMETHODIMP FindPin(LPCWSTR Id, IPin **ppPin); + + STDMETHODIMP JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName); + + STDMETHODIMP QueryFilterInfo(FILTER_INFO *pInfo); + STDMETHODIMP QueryVendorInfo(LPWSTR *pVendorInfo); + +protected: + QMutex m_mutex; + FILTER_STATE m_state; + IFilterGraph *m_graph; + IReferenceClock *m_clock; + IMediaEventSink *m_sink; + QString m_filterName; + REFERENCE_TIME m_startTime; + +private: + Q_DISABLE_COPY(DirectShowBaseFilter) +}; + +QT_END_NAMESPACE + +#endif // DIRECTSHOWBASEFILTER_H diff --git a/src/plugins/directshow/common/directshoweventloop.cpp b/src/plugins/directshow/common/directshoweventloop.cpp new file mode 100644 index 000000000..ef85c0429 --- /dev/null +++ b/src/plugins/directshow/common/directshoweventloop.cpp @@ -0,0 +1,152 @@ +/**************************************************************************** +** +** 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 + +#include +#include + +QT_BEGIN_NAMESPACE + +class DirectShowPostedEvent +{ +public: + DirectShowPostedEvent(QObject *receiver, QEvent *event) + : receiver(receiver) + , event(event) + , next(0) + { + } + + ~DirectShowPostedEvent() + { + delete event; + } + + QObject *receiver; + QEvent *event; + DirectShowPostedEvent *next; +}; + +DirectShowEventLoop::DirectShowEventLoop(QObject *parent) + : QObject(parent) + , m_postsHead(0) + , m_postsTail(0) + , m_eventHandle(::CreateEvent(0, 0, 0, 0)) + , m_waitHandle(::CreateEvent(0, 0, 0, 0)) +{ +} + +DirectShowEventLoop::~DirectShowEventLoop() +{ + ::CloseHandle(m_eventHandle); + ::CloseHandle(m_waitHandle); + + for (DirectShowPostedEvent *post = m_postsHead; post; post = m_postsHead) { + m_postsHead = m_postsHead->next; + + delete post; + } +} + +void DirectShowEventLoop::wait(QMutex *mutex) +{ + ::ResetEvent(m_waitHandle); + + mutex->unlock(); + + HANDLE handles[] = { m_eventHandle, m_waitHandle }; + while (::WaitForMultipleObjects(2, handles, false, INFINITE) == WAIT_OBJECT_0) + processEvents(); + + mutex->lock(); +} + +void DirectShowEventLoop::wake() +{ + ::SetEvent(m_waitHandle); +} + +void DirectShowEventLoop::postEvent(QObject *receiver, QEvent *event) +{ + QMutexLocker locker(&m_mutex); + + DirectShowPostedEvent *post = new DirectShowPostedEvent(receiver, event); + + if (m_postsTail) + m_postsTail->next = post; + else + m_postsHead = post; + + m_postsTail = post; + + QCoreApplication::postEvent(this, new QEvent(QEvent::User)); + ::SetEvent(m_eventHandle); +} + +void DirectShowEventLoop::customEvent(QEvent *event) +{ + if (event->type() == QEvent::User) { + processEvents(); + } else { + QObject::customEvent(event); + } +} + +void DirectShowEventLoop::processEvents() +{ + QMutexLocker locker(&m_mutex); + + ::ResetEvent(m_eventHandle); + + while(m_postsHead) { + DirectShowPostedEvent *post = m_postsHead; + m_postsHead = m_postsHead->next; + + if (!m_postsHead) + m_postsTail = 0; + + locker.unlock(); + QCoreApplication::sendEvent(post->receiver, post->event); + delete post; + locker.relock(); + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/directshow/common/directshoweventloop.h b/src/plugins/directshow/common/directshoweventloop.h new file mode 100644 index 000000000..609e53134 --- /dev/null +++ b/src/plugins/directshow/common/directshoweventloop.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTSHOWEVENTLOOP_H +#define DIRECTSHOWEVENTLOOP_H + +#include +#include +#include + +#include + +QT_BEGIN_NAMESPACE + +class DirectShowPostedEvent; + +class DirectShowEventLoop : public QObject +{ + Q_OBJECT +public: + DirectShowEventLoop(QObject *parent = 0); + ~DirectShowEventLoop(); + + void wait(QMutex *mutex); + void wake(); + + void postEvent(QObject *object, QEvent *event); + +protected: + void customEvent(QEvent *event); + +private: + void processEvents(); + + DirectShowPostedEvent *m_postsHead; + DirectShowPostedEvent *m_postsTail; + HANDLE m_eventHandle; + HANDLE m_waitHandle; + QMutex m_mutex; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/directshow/common/directshowglobal.h b/src/plugins/directshow/common/directshowglobal.h new file mode 100644 index 000000000..5f391710e --- /dev/null +++ b/src/plugins/directshow/common/directshowglobal.h @@ -0,0 +1,160 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTSHOWGLOBAL_H +#define DIRECTSHOWGLOBAL_H + +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +Q_DECLARE_LOGGING_CATEGORY(qtDirectShowPlugin) + +QT_END_NAMESPACE + +template T *com_cast(IUnknown *unknown, const IID &iid) +{ + T *iface = 0; + return unknown && unknown->QueryInterface(iid, reinterpret_cast(&iface)) == S_OK + ? iface + : 0; +} + +template T *com_new(const IID &clsid) +{ + T *object = 0; + return CoCreateInstance( + clsid, + NULL, + CLSCTX_INPROC_SERVER, + IID_PPV_ARGS(&object)) == S_OK + ? object + : 0; +} + +template T *com_new(const IID &clsid, const IID &iid) +{ + T *object = 0; + return CoCreateInstance( + clsid, + NULL, + CLSCTX_INPROC_SERVER, + iid, + reinterpret_cast(&object)) == S_OK + ? object + : 0; +} + +DEFINE_GUID(MEDIASUBTYPE_I420, + 0x30323449,0x0000,0x0010,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71); + +#ifndef __IFilterGraph2_INTERFACE_DEFINED__ +#define __IFilterGraph2_INTERFACE_DEFINED__ +#define INTERFACE IFilterGraph2 +DECLARE_INTERFACE_(IFilterGraph2 ,IGraphBuilder) +{ + STDMETHOD(AddSourceFilterForMoniker)(THIS_ IMoniker *, IBindCtx *, LPCWSTR,IBaseFilter **) PURE; + STDMETHOD(ReconnectEx)(THIS_ IPin *, const AM_MEDIA_TYPE *) PURE; + STDMETHOD(RenderEx)(IPin *, DWORD, DWORD *) PURE; +}; +#undef INTERFACE +#endif + +#ifndef __IAMFilterMiscFlags_INTERFACE_DEFINED__ +#define __IAMFilterMiscFlags_INTERFACE_DEFINED__ +#define INTERFACE IAMFilterMiscFlags +DECLARE_INTERFACE_(IAMFilterMiscFlags ,IUnknown) +{ + STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + STDMETHOD_(ULONG,GetMiscFlags)(THIS) PURE; +}; +#undef INTERFACE +#endif + +#ifndef __IFileSourceFilter_INTERFACE_DEFINED__ +#define __IFileSourceFilter_INTERFACE_DEFINED__ +#define INTERFACE IFileSourceFilter +DECLARE_INTERFACE_(IFileSourceFilter ,IUnknown) +{ + STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + STDMETHOD(Load)(THIS_ LPCOLESTR, const AM_MEDIA_TYPE *) PURE; + STDMETHOD(GetCurFile)(THIS_ LPOLESTR *ppszFileName, AM_MEDIA_TYPE *) PURE; +}; +#undef INTERFACE +#endif + +#ifndef __IAMOpenProgress_INTERFACE_DEFINED__ +#define __IAMOpenProgress_INTERFACE_DEFINED__ +#undef INTERFACE +#define INTERFACE IAMOpenProgress +DECLARE_INTERFACE_(IAMOpenProgress ,IUnknown) +{ + STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + STDMETHOD(QueryProgress)(THIS_ LONGLONG *, LONGLONG *) PURE; + STDMETHOD(AbortOperation)(THIS) PURE; +}; +#undef INTERFACE +#endif + +#ifndef __IFilterChain_INTERFACE_DEFINED__ +#define __IFilterChain_INTERFACE_DEFINED__ +#define INTERFACE IFilterChain +DECLARE_INTERFACE_(IFilterChain ,IUnknown) +{ + STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + STDMETHOD(StartChain)(IBaseFilter *, IBaseFilter *) PURE; + STDMETHOD(PauseChain)(IBaseFilter *, IBaseFilter *) PURE; + STDMETHOD(StopChain)(IBaseFilter *, IBaseFilter *) PURE; + STDMETHOD(RemoveChain)(IBaseFilter *, IBaseFilter *) PURE; +}; +#undef INTERFACE +#endif + +#endif diff --git a/src/plugins/directshow/common/directshowmediatype.cpp b/src/plugins/directshow/common/directshowmediatype.cpp new file mode 100644 index 000000000..65882806c --- /dev/null +++ b/src/plugins/directshow/common/directshowmediatype.cpp @@ -0,0 +1,350 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "directshowmediatype.h" +#include "directshowglobal.h" + +namespace +{ + struct TypeLookup + { + QVideoFrame::PixelFormat pixelFormat; + GUID mediaType; + }; + + static const TypeLookup qt_typeLookup[] = + { + { QVideoFrame::Format_ARGB32, MEDIASUBTYPE_ARGB32 }, + { QVideoFrame::Format_RGB32, MEDIASUBTYPE_RGB32 }, + { QVideoFrame::Format_RGB24, MEDIASUBTYPE_RGB24 }, + { QVideoFrame::Format_RGB565, MEDIASUBTYPE_RGB565 }, + { QVideoFrame::Format_RGB555, MEDIASUBTYPE_RGB555 }, + { QVideoFrame::Format_AYUV444, MEDIASUBTYPE_AYUV }, + { QVideoFrame::Format_YUYV, MEDIASUBTYPE_YUY2 }, + { QVideoFrame::Format_UYVY, MEDIASUBTYPE_UYVY }, + { QVideoFrame::Format_IMC1, MEDIASUBTYPE_IMC1 }, + { QVideoFrame::Format_IMC2, MEDIASUBTYPE_IMC2 }, + { QVideoFrame::Format_IMC3, MEDIASUBTYPE_IMC3 }, + { QVideoFrame::Format_IMC4, MEDIASUBTYPE_IMC4 }, + { QVideoFrame::Format_YV12, MEDIASUBTYPE_YV12 }, + { QVideoFrame::Format_NV12, MEDIASUBTYPE_NV12 }, + { QVideoFrame::Format_YUV420P, MEDIASUBTYPE_IYUV }, + { QVideoFrame::Format_YUV420P, MEDIASUBTYPE_I420 }, + { QVideoFrame::Format_Jpeg, MEDIASUBTYPE_MJPG } + }; +} + +bool DirectShowMediaType::isPartiallySpecified(const AM_MEDIA_TYPE *mediaType) +{ + return mediaType->majortype == GUID_NULL || mediaType->formattype == GUID_NULL; +} + +DirectShowMediaType::DirectShowMediaType() + : mediaType({ GUID_NULL, GUID_NULL, TRUE, FALSE, 1, GUID_NULL, nullptr, 0, nullptr}) +{ +} + +DirectShowMediaType::DirectShowMediaType(const AM_MEDIA_TYPE &type) + : DirectShowMediaType() +{ + copy(&mediaType, &type); +} + +DirectShowMediaType::DirectShowMediaType(AM_MEDIA_TYPE &&type) + : DirectShowMediaType() +{ + move(&mediaType, type); +} + +DirectShowMediaType::DirectShowMediaType(const DirectShowMediaType &other) + : DirectShowMediaType() +{ + copy(&mediaType, &other.mediaType); +} + +DirectShowMediaType::DirectShowMediaType(DirectShowMediaType &&other) + : DirectShowMediaType() +{ + move(&mediaType, other.mediaType); +} + +DirectShowMediaType &DirectShowMediaType::operator=(const DirectShowMediaType &other) +{ + copy(&mediaType, &other.mediaType); + return *this; +} + +DirectShowMediaType &DirectShowMediaType::operator=(DirectShowMediaType &&other) +{ + move(&mediaType, other.mediaType); + return *this; +} + +void DirectShowMediaType::init(AM_MEDIA_TYPE *type) +{ + Q_ASSERT(type); + SecureZeroMemory(reinterpret_cast(type), sizeof(AM_MEDIA_TYPE)); + type->lSampleSize = 1; + type->bFixedSizeSamples = TRUE; +} + +void DirectShowMediaType::copy(AM_MEDIA_TYPE *target, const AM_MEDIA_TYPE *source) +{ + if (!(target && source)) + return; + + if (target == source) + return; + + clear(*target); + + copyToUninitialized(target, source); +} + +void DirectShowMediaType::copyToUninitialized(AM_MEDIA_TYPE *target, const AM_MEDIA_TYPE *source) +{ + *target = *source; + + if (source->cbFormat > 0) { + target->pbFormat = reinterpret_cast(CoTaskMemAlloc(source->cbFormat)); + memcpy(target->pbFormat, source->pbFormat, source->cbFormat); + } + if (target->pUnk) + target->pUnk->AddRef(); +} + +void DirectShowMediaType::move(AM_MEDIA_TYPE *target, AM_MEDIA_TYPE **source) +{ + if (!target || !source || !(*source)) + return; + + if (target == *source) + return; + + clear(*target); + *target = *(*source); + SecureZeroMemory(reinterpret_cast(*source), sizeof(AM_MEDIA_TYPE)); + *source = nullptr; +} + +void DirectShowMediaType::move(AM_MEDIA_TYPE *target, AM_MEDIA_TYPE &source) +{ + AM_MEDIA_TYPE *srcPtr = &source; + move(target, &srcPtr); +} + +/** + * @brief DirectShowMediaType::deleteType - Used for AM_MEDIA_TYPE structures that have + * been allocated by CoTaskMemAlloc or CreateMediaType. + * @param type + */ +void DirectShowMediaType::deleteType(AM_MEDIA_TYPE *type) +{ + if (!type) + return; + + clear(*type); + CoTaskMemFree(type); +} + +bool DirectShowMediaType::isCompatible(const AM_MEDIA_TYPE *a, const AM_MEDIA_TYPE *b) +{ + if (b->majortype != GUID_NULL && a->majortype != b->majortype) + return false; + + if (b->subtype != GUID_NULL && a->subtype != b->subtype) + return false; + + if (b->formattype != GUID_NULL) { + if (a->formattype != b->formattype) + return false; + if (a->cbFormat != b->cbFormat) + return false; + if (a->cbFormat != 0 && memcmp(a->pbFormat, b->pbFormat, a->cbFormat) != 0) + return false; + } + + return true; +} + +/** + * @brief DirectShowMediaType::clear - Clears all member data, and releases allocated buffers. + * Use this to release automatic AM_MEDIA_TYPE structures. + * @param type + */ +void DirectShowMediaType::clear(AM_MEDIA_TYPE &type) +{ + if (type.cbFormat > 0) + CoTaskMemFree(type.pbFormat); + + if (type.pUnk) + type.pUnk->Release(); + + SecureZeroMemory(&type, sizeof(type)); +} + + +GUID DirectShowMediaType::convertPixelFormat(QVideoFrame::PixelFormat format) +{ + const int count = sizeof(qt_typeLookup) / sizeof(TypeLookup); + + for (int i = 0; i < count; ++i) + if (qt_typeLookup[i].pixelFormat == format) + return qt_typeLookup[i].mediaType; + + return MEDIASUBTYPE_None; +} + +QVideoSurfaceFormat DirectShowMediaType::videoFormatFromType(const AM_MEDIA_TYPE *type) +{ + if (!type) + return QVideoSurfaceFormat(); + + const int count = sizeof(qt_typeLookup) / sizeof(TypeLookup); + + for (int i = 0; i < count; ++i) { + if (IsEqualGUID(qt_typeLookup[i].mediaType, type->subtype) && type->cbFormat > 0) { + if (IsEqualGUID(type->formattype, FORMAT_VideoInfo)) { + VIDEOINFOHEADER *header = reinterpret_cast(type->pbFormat); + + QVideoSurfaceFormat format( + QSize(header->bmiHeader.biWidth, qAbs(header->bmiHeader.biHeight)), + qt_typeLookup[i].pixelFormat); + + if (header->AvgTimePerFrame > 0) + format.setFrameRate(10000 /header->AvgTimePerFrame); + + format.setScanLineDirection(scanLineDirection(format.pixelFormat(), header->bmiHeader)); + + return format; + } else if (IsEqualGUID(type->formattype, FORMAT_VideoInfo2)) { + VIDEOINFOHEADER2 *header = reinterpret_cast(type->pbFormat); + + QVideoSurfaceFormat format( + QSize(header->bmiHeader.biWidth, qAbs(header->bmiHeader.biHeight)), + qt_typeLookup[i].pixelFormat); + + if (header->AvgTimePerFrame > 0) + format.setFrameRate(10000 / header->AvgTimePerFrame); + + format.setScanLineDirection(scanLineDirection(format.pixelFormat(), header->bmiHeader)); + + return format; + } + } + } + return QVideoSurfaceFormat(); +} + +QVideoFrame::PixelFormat DirectShowMediaType::pixelFormatFromType(const AM_MEDIA_TYPE *type) +{ + if (!type) + return QVideoFrame::Format_Invalid; + + const int count = sizeof(qt_typeLookup) / sizeof(TypeLookup); + + for (int i = 0; i < count; ++i) { + if (IsEqualGUID(qt_typeLookup[i].mediaType, type->subtype)) { + return qt_typeLookup[i].pixelFormat; + } + } + + return QVideoFrame::Format_Invalid; +} + +#define PAD_TO_DWORD(x) (((x) + 3) & ~3) +int DirectShowMediaType::bytesPerLine(const QVideoSurfaceFormat &format) +{ + switch (format.pixelFormat()) { + // 32 bpp packed formats. + case QVideoFrame::Format_ARGB32: + case QVideoFrame::Format_RGB32: + case QVideoFrame::Format_AYUV444: + return format.frameWidth() * 4; + // 24 bpp packed formats. + case QVideoFrame::Format_RGB24: + return PAD_TO_DWORD(format.frameWidth() * 3); + // 16 bpp packed formats. + case QVideoFrame::Format_RGB565: + case QVideoFrame::Format_RGB555: + case QVideoFrame::Format_YUYV: + case QVideoFrame::Format_UYVY: + return PAD_TO_DWORD(format.frameWidth() * 2); + // Planar formats. + case QVideoFrame::Format_YV12: + case QVideoFrame::Format_YUV420P: + case QVideoFrame::Format_IMC1: + case QVideoFrame::Format_IMC2: + case QVideoFrame::Format_IMC3: + case QVideoFrame::Format_IMC4: + case QVideoFrame::Format_NV12: + return format.frameWidth(); + default: + return 0; + } +} + +QVideoSurfaceFormat::Direction DirectShowMediaType::scanLineDirection(QVideoFrame::PixelFormat pixelFormat, const BITMAPINFOHEADER &bmiHeader) +{ + /* MSDN http://msdn.microsoft.com/en-us/library/windows/desktop/dd318229(v=vs.85).aspx */ + /* For uncompressed RGB bitmaps: + * if biHeight is positive, the bitmap is a bottom-up DIB with the origin at the lower left corner. + * If biHeight is negative, the bitmap is a top-down DIB with the origin at the upper left corner. + * + * For YUV bitmaps: + * the bitmap is always top-down, regardless of the sign of biHeight. + * Decoders should offer YUV formats with postive biHeight, but for backward compatibility they should accept YUV formats with either positive or negative biHeight. + * + * For compressed formats: + * biHeight must be positive, regardless of image orientation. + */ + switch (pixelFormat) + { + case QVideoFrame::Format_ARGB32: + case QVideoFrame::Format_RGB32: + case QVideoFrame::Format_RGB24: + case QVideoFrame::Format_RGB565: + case QVideoFrame::Format_RGB555: + return bmiHeader.biHeight < 0 + ? QVideoSurfaceFormat::TopToBottom + : QVideoSurfaceFormat::BottomToTop; + default: + return QVideoSurfaceFormat::TopToBottom; + } +} diff --git a/src/plugins/directshow/common/directshowmediatype.h b/src/plugins/directshow/common/directshowmediatype.h new file mode 100644 index 000000000..7f495f3b2 --- /dev/null +++ b/src/plugins/directshow/common/directshowmediatype.h @@ -0,0 +1,97 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTSHOWMEDIATYPE_H +#define DIRECTSHOWMEDIATYPE_H + +#include + +#include + +#include +#include + +QT_BEGIN_NAMESPACE + +class DirectShowMediaType +{ +public: + DirectShowMediaType(); + DirectShowMediaType(const DirectShowMediaType &other); + DirectShowMediaType(DirectShowMediaType &&other); + explicit DirectShowMediaType(const AM_MEDIA_TYPE &type); + explicit DirectShowMediaType(AM_MEDIA_TYPE &&type); + ~DirectShowMediaType() { clear(mediaType); } + + DirectShowMediaType &operator =(const DirectShowMediaType &other); + DirectShowMediaType &operator =(DirectShowMediaType &&other); + + void clear() { clear(mediaType); } + + inline AM_MEDIA_TYPE *operator &() Q_DECL_NOTHROW { return &mediaType; } + inline AM_MEDIA_TYPE *operator ->() Q_DECL_NOTHROW { return &mediaType; } + + inline const AM_MEDIA_TYPE *operator &() const Q_DECL_NOTHROW { return &mediaType; } + inline const AM_MEDIA_TYPE *operator ->() const Q_DECL_NOTHROW { return &mediaType; } + + static void init(AM_MEDIA_TYPE *type); + static void copy(AM_MEDIA_TYPE *target, const AM_MEDIA_TYPE *source); + static void copyToUninitialized(AM_MEDIA_TYPE *target, const AM_MEDIA_TYPE *source); + static void move(AM_MEDIA_TYPE *target, AM_MEDIA_TYPE **source); + static void move(AM_MEDIA_TYPE *target, AM_MEDIA_TYPE &source); + static void clear(AM_MEDIA_TYPE &type); + static void deleteType(AM_MEDIA_TYPE *type); + static bool isPartiallySpecified(const AM_MEDIA_TYPE *mediaType); + static bool isCompatible(const AM_MEDIA_TYPE *a, const AM_MEDIA_TYPE *b); + static GUID convertPixelFormat(QVideoFrame::PixelFormat format); + + static QVideoSurfaceFormat videoFormatFromType(const AM_MEDIA_TYPE *type); + static QVideoFrame::PixelFormat pixelFormatFromType(const AM_MEDIA_TYPE *type); + static int bytesPerLine(const QVideoSurfaceFormat &format); + static QVideoSurfaceFormat::Direction scanLineDirection(QVideoFrame::PixelFormat pixelFormat, const BITMAPINFOHEADER &bmiHeader); + +private: + AM_MEDIA_TYPE mediaType; +}; + +Q_DECLARE_TYPEINFO(DirectShowMediaType, Q_MOVABLE_TYPE); + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/directshow/common/directshowmediatypeenum.cpp b/src/plugins/directshow/common/directshowmediatypeenum.cpp new file mode 100644 index 000000000..8fbdf7dea --- /dev/null +++ b/src/plugins/directshow/common/directshowmediatypeenum.cpp @@ -0,0 +1,117 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "directshowmediatypeenum.h" + +#include "directshowpin.h" + +DirectShowMediaTypeEnum::DirectShowMediaTypeEnum(DirectShowPin *pin) + : m_pin(pin) + , m_mediaTypes(pin->supportedMediaTypes()) + , m_index(0) +{ + m_pin->AddRef(); +} + +DirectShowMediaTypeEnum::DirectShowMediaTypeEnum(const QList &types) + : m_pin(NULL) + , m_mediaTypes(types) + , m_index(0) +{ +} + +DirectShowMediaTypeEnum::~DirectShowMediaTypeEnum() +{ + if (m_pin) + m_pin->Release(); +} + +HRESULT DirectShowMediaTypeEnum::getInterface(REFIID riid, void **ppvObject) +{ + if (riid == IID_IEnumMediaTypes) { + return GetInterface(static_cast(this), ppvObject); + } else { + return DirectShowObject::getInterface(riid, ppvObject); + } +} + +HRESULT DirectShowMediaTypeEnum::Next(ULONG cMediaTypes, AM_MEDIA_TYPE **ppMediaTypes, ULONG *pcFetched) +{ + if (ppMediaTypes && (pcFetched || cMediaTypes == 1)) { + ULONG count = qBound(0, cMediaTypes, m_mediaTypes.count() - m_index); + + for (ULONG i = 0; i < count; ++i, ++m_index) { + ppMediaTypes[i] = reinterpret_cast(CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE))); + DirectShowMediaType::copyToUninitialized(ppMediaTypes[i], &m_mediaTypes.at(m_index)); + } + + if (pcFetched) + *pcFetched = count; + + return count == cMediaTypes ? S_OK : S_FALSE; + } else { + return E_POINTER; + } +} + +HRESULT DirectShowMediaTypeEnum::Skip(ULONG cMediaTypes) +{ + m_index = qMin(int(m_index + cMediaTypes), m_mediaTypes.count()); + return m_index < m_mediaTypes.count() ? S_OK : S_FALSE; +} + +HRESULT DirectShowMediaTypeEnum::Reset() +{ + m_index = 0; + return S_OK; +} + +HRESULT DirectShowMediaTypeEnum::Clone(IEnumMediaTypes **ppEnum) +{ + if (ppEnum) { + if (m_pin) + *ppEnum = new DirectShowMediaTypeEnum(m_pin); + else + *ppEnum = new DirectShowMediaTypeEnum(m_mediaTypes); + return S_OK; + } else { + return E_POINTER; + } +} + diff --git a/src/plugins/directshow/common/directshowmediatypeenum.h b/src/plugins/directshow/common/directshowmediatypeenum.h new file mode 100644 index 000000000..9b058fc5b --- /dev/null +++ b/src/plugins/directshow/common/directshowmediatypeenum.h @@ -0,0 +1,80 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTSHOWMEDIATYPEENUM_H +#define DIRECTSHOWMEDIATYPEENUM_H + +#include "directshowobject.h" +#include + +QT_BEGIN_NAMESPACE + +class DirectShowPin; +class DirectShowMediaType; + +class DirectShowMediaTypeEnum : public DirectShowObject + , public IEnumMediaTypes +{ + DIRECTSHOW_OBJECT + +public: + DirectShowMediaTypeEnum(DirectShowPin *pin); + DirectShowMediaTypeEnum(const QList &types); + ~DirectShowMediaTypeEnum(); + + // DirectShowObject + HRESULT getInterface(REFIID riid, void **ppvObject); + + // IEnumMediaTypes + STDMETHODIMP Next(ULONG cMediaTypes, AM_MEDIA_TYPE **ppMediaTypes, ULONG *pcFetched); + STDMETHODIMP Skip(ULONG cMediaTypes); + STDMETHODIMP Reset(); + STDMETHODIMP Clone(IEnumMediaTypes **ppEnum); + +private: + Q_DISABLE_COPY(DirectShowMediaTypeEnum) + + DirectShowPin *m_pin; + QList m_mediaTypes; + int m_index; +}; + +QT_END_NAMESPACE + +#endif // DIRECTSHOWMEDIATYPEENUM_H diff --git a/src/plugins/directshow/common/directshowobject.cpp b/src/plugins/directshow/common/directshowobject.cpp new file mode 100644 index 000000000..db1817a8d --- /dev/null +++ b/src/plugins/directshow/common/directshowobject.cpp @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** 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 "directshowobject.h" + +QT_BEGIN_NAMESPACE + +DirectShowObject::DirectShowObject() + : m_ref(1) +{ +} + +DirectShowObject::~DirectShowObject() +{ + Q_ASSERT(m_ref == 0); +} + +HRESULT DirectShowObject::getInterface(const IID &riid, void **ppvObject) +{ + Q_UNUSED(riid) + *ppvObject = NULL; + return E_NOINTERFACE; +} + +ULONG DirectShowObject::ref() +{ + return InterlockedIncrement(&m_ref); +} + +ULONG DirectShowObject::unref() +{ + ULONG ref = InterlockedDecrement(&m_ref); + if (ref == 0) + delete this; + + return ref; +} + +HRESULT GetInterface(IUnknown *pUnk, void **ppv) +{ + if (!ppv) + return E_POINTER; + + *ppv = pUnk; + pUnk->AddRef(); + + return S_OK; +} + +QT_END_NAMESPACE diff --git a/src/plugins/directshow/common/directshowobject.h b/src/plugins/directshow/common/directshowobject.h new file mode 100644 index 000000000..cfac16f61 --- /dev/null +++ b/src/plugins/directshow/common/directshowobject.h @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTSHOWOBJECT_H +#define DIRECTSHOWOBJECT_H + +#include "directshowglobal.h" + +QT_BEGIN_NAMESPACE + +class DirectShowObject +{ +public: + DirectShowObject(); + virtual ~DirectShowObject(); + + virtual HRESULT getInterface(REFIID riid, void **ppvObject); + ULONG ref(); + ULONG unref(); + +private: + Q_DISABLE_COPY(DirectShowObject) + + volatile LONG m_ref; +}; + +HRESULT GetInterface(IUnknown *pUnk, void **ppv); + +#define DIRECTSHOW_OBJECT \ +public: \ + STDMETHODIMP QueryInterface(REFIID riid, void **ppv) { \ + if (riid == IID_IUnknown) \ + return GetInterface(reinterpret_cast(this), ppv); \ + else \ + return getInterface(riid, ppv); \ + }; \ + STDMETHODIMP_(ULONG) AddRef() { \ + return ref(); \ + }; \ + STDMETHODIMP_(ULONG) Release() { \ + return unref(); \ + }; + +QT_END_NAMESPACE + +#endif // DIRECTSHOWOBJECT_H diff --git a/src/plugins/directshow/common/directshowpin.cpp b/src/plugins/directshow/common/directshowpin.cpp new file mode 100644 index 000000000..b49c3f8a4 --- /dev/null +++ b/src/plugins/directshow/common/directshowpin.cpp @@ -0,0 +1,740 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "directshowpin.h" + +#include "directshowmediatype.h" +#include "directshowbasefilter.h" +#include "directshowmediatypeenum.h" + +#include + +QT_BEGIN_NAMESPACE + +DirectShowPin::DirectShowPin(DirectShowBaseFilter *filter, const QString &name, PIN_DIRECTION direction) + : m_mutex(QMutex::Recursive) + , m_filter(filter) + , m_name(name) + , m_direction(direction) + , m_peerPin(NULL) +{ +} + +DirectShowPin::~DirectShowPin() +{ + +} + +HRESULT DirectShowPin::getInterface(const IID &riid, void **ppvObject) +{ + if (riid == IID_IPin) + return GetInterface(static_cast(this), ppvObject); + else + return DirectShowObject::getInterface(riid, ppvObject); +} + + + +HRESULT DirectShowPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) +{ + if (!pReceivePin) + return E_POINTER; + + HRESULT hr = E_FAIL; + QMutexLocker locker(&m_mutex); + + if (m_peerPin) + return VFW_E_ALREADY_CONNECTED; + if (m_filter->state() != State_Stopped) + return VFW_E_NOT_STOPPED; + + PIN_DIRECTION pd; + pReceivePin->QueryDirection(&pd); + if (pd == m_direction) + return VFW_E_INVALID_DIRECTION; + + if (pmt != NULL && DirectShowMediaType::isPartiallySpecified(pmt)) { + // If the type is fully specified, use it + hr = tryConnect(pReceivePin, pmt); + } else { + IEnumMediaTypes *enumMediaTypes = NULL; + + // First, try the receiving pin's preferred types + if (SUCCEEDED(pReceivePin->EnumMediaTypes(&enumMediaTypes))) { + hr = tryMediaTypes(pReceivePin, pmt, enumMediaTypes); + enumMediaTypes->Release(); + } + // Then, try this pin's preferred types + if (FAILED(hr) && SUCCEEDED(EnumMediaTypes(&enumMediaTypes))) { + hr = tryMediaTypes(pReceivePin, pmt, enumMediaTypes); + enumMediaTypes->Release(); + } + } + + if (FAILED(hr)) { + return ((hr != E_FAIL) && (hr != E_INVALIDARG) && (hr != VFW_E_TYPE_NOT_ACCEPTED)) + ? hr : VFW_E_NO_ACCEPTABLE_TYPES; + } + + return S_OK; +} + +HRESULT DirectShowPin::tryMediaTypes(IPin *pin, const AM_MEDIA_TYPE *partialType, IEnumMediaTypes *enumMediaTypes) +{ + HRESULT hr = enumMediaTypes->Reset(); + if (FAILED(hr)) + return hr; + + AM_MEDIA_TYPE *mediaType = NULL; + ULONG mediaCount = 0; + HRESULT hrFailure = VFW_E_NO_ACCEPTABLE_TYPES; + + for (; enumMediaTypes->Next(1, &mediaType, &mediaCount) == S_OK;) { + + if (mediaType && (partialType == NULL || DirectShowMediaType::isCompatible(mediaType, partialType))) { + hr = tryConnect(pin, mediaType); + + if (FAILED(hr) && (hr != E_FAIL) + && (hr != E_INVALIDARG) + && (hr != VFW_E_TYPE_NOT_ACCEPTED)) { + hrFailure = hr; + } + } + + if (mediaType) + DirectShowMediaType::deleteType(mediaType); + + if (SUCCEEDED(hr)) + return S_OK; + } + + return hrFailure; +} + +HRESULT DirectShowPin::tryConnect(IPin *pin, const AM_MEDIA_TYPE *type) +{ + if (!isMediaTypeSupported(type)) + return VFW_E_TYPE_NOT_ACCEPTED; + + m_peerPin = pin; + m_peerPin->AddRef(); + + HRESULT hr; + if (!setMediaType(type)) { + hr = VFW_E_TYPE_NOT_ACCEPTED; + } else { + hr = pin->ReceiveConnection(this, type); + if (SUCCEEDED(hr)) { + hr = completeConnection(pin); + if (FAILED(hr)) + pin->Disconnect(); + } + } + + if (FAILED(hr)) { + connectionEnded(); + m_peerPin->Release(); + m_peerPin = NULL; + setMediaType(NULL); + return hr; + } + + return S_OK; +} + +HRESULT DirectShowPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt) +{ + if (!pConnector || !pmt) + return E_POINTER; + + QMutexLocker locker(&m_mutex); + + if (m_peerPin) + return VFW_E_ALREADY_CONNECTED; + if (m_filter->state() != State_Stopped) + return VFW_E_NOT_STOPPED; + + PIN_DIRECTION pd; + pConnector->QueryDirection(&pd); + if (pd == m_direction) + return VFW_E_INVALID_DIRECTION; + + if (!isMediaTypeSupported(pmt)) + return VFW_E_TYPE_NOT_ACCEPTED; + + m_peerPin = pConnector; + m_peerPin->AddRef(); + + HRESULT hr; + if (!setMediaType(pmt)) + hr = VFW_E_TYPE_NOT_ACCEPTED; + else + hr = completeConnection(pConnector); + + if (FAILED(hr)) { + connectionEnded(); + m_peerPin->Release(); + m_peerPin = NULL; + setMediaType(NULL); + return hr; + } + + return S_OK; +} + +HRESULT DirectShowPin::Disconnect() +{ + QMutexLocker locker(&m_mutex); + + if (m_filter->state() != State_Stopped) + return VFW_E_NOT_STOPPED; + + if (m_peerPin) { + HRESULT hr = connectionEnded(); + if (FAILED(hr)) + return hr; + + m_peerPin->Release(); + m_peerPin = NULL; + + setMediaType(NULL); + + return S_OK; + } + + return S_FALSE; +} + +HRESULT DirectShowPin::ConnectedTo(IPin **ppPin) +{ + if (!ppPin) { + return E_POINTER; + } else { + QMutexLocker locker(&m_mutex); + + if (!m_peerPin) { + *ppPin = 0; + return VFW_E_NOT_CONNECTED; + } else { + m_peerPin->AddRef(); + *ppPin = m_peerPin; + return S_OK; + } + } +} + +HRESULT DirectShowPin::ConnectionMediaType(AM_MEDIA_TYPE *pmt) +{ + if (!pmt) { + return E_POINTER; + } else { + QMutexLocker locker(&m_mutex); + + if (!m_peerPin) { + DirectShowMediaType::init(pmt); + return VFW_E_NOT_CONNECTED; + } else { + DirectShowMediaType::copy(pmt, &m_mediaType); + return S_OK; + } + } +} + +HRESULT DirectShowPin::QueryPinInfo(PIN_INFO *pInfo) +{ + if (!pInfo) { + return E_POINTER; + } else { + pInfo->pFilter = m_filter; + if (m_filter) { + m_filter->AddRef(); + } + pInfo->dir = m_direction; + + QString name = m_name; + if (name.length() >= MAX_PIN_NAME) + name.truncate(MAX_PIN_NAME - 1); + int length = name.toWCharArray(pInfo->achName); + pInfo->achName[length] = '\0'; + + return S_OK; + } +} + +HRESULT DirectShowPin::QueryId(LPWSTR *Id) +{ + if (!Id) { + return E_POINTER; + } else { + const int bytes = (m_name.length() + 1) * 2; + *Id = static_cast(::CoTaskMemAlloc(bytes)); + ::memcpy(*Id, m_name.utf16(), bytes); + return S_OK; + } +} + +HRESULT DirectShowPin::QueryAccept(const AM_MEDIA_TYPE *pmt) +{ + if (!pmt) + return E_POINTER; + + if (!isMediaTypeSupported(pmt)) + return S_FALSE; + + return S_OK; +} + +HRESULT DirectShowPin::EnumMediaTypes(IEnumMediaTypes **ppEnum) +{ + if (!ppEnum) { + return E_POINTER; + } else { + *ppEnum = new DirectShowMediaTypeEnum(this); + return S_OK; + } +} + +HRESULT DirectShowPin::QueryInternalConnections(IPin **apPin, ULONG *nPin) +{ + Q_UNUSED(apPin); + Q_UNUSED(nPin); + return E_NOTIMPL; +} + +HRESULT DirectShowPin::EndOfStream() +{ + return S_OK; +} + +HRESULT DirectShowPin::BeginFlush() +{ + return E_UNEXPECTED; +} + +HRESULT DirectShowPin::EndFlush() +{ + return E_UNEXPECTED; +} + +HRESULT DirectShowPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) +{ + Q_UNUSED(tStart); + Q_UNUSED(tStop); + Q_UNUSED(dRate); + return S_OK; +} + +HRESULT DirectShowPin::QueryDirection(PIN_DIRECTION *pPinDir) +{ + if (!pPinDir) { + return E_POINTER; + } else { + *pPinDir = m_direction; + return S_OK; + } +} + +QList DirectShowPin::supportedMediaTypes() +{ + return QList(); +} + +bool DirectShowPin::setMediaType(const AM_MEDIA_TYPE *type) +{ + if (!type) + m_mediaType.clear(); + else + DirectShowMediaType::copy(&m_mediaType, type); + + return true; +} + +HRESULT DirectShowPin::completeConnection(IPin *pin) +{ + Q_UNUSED(pin) + return S_OK; +} + +HRESULT DirectShowPin::connectionEnded() +{ + return S_OK; +} + +HRESULT DirectShowPin::setActive(bool active) +{ + Q_UNUSED(active) + return S_OK; +} + + +/* DirectShowOutputPin */ + +DirectShowOutputPin::DirectShowOutputPin(DirectShowBaseFilter *filter, const QString &name) + : DirectShowPin(filter, name, PINDIR_OUTPUT) + , m_allocator(NULL) + , m_inputPin(NULL) +{ + +} + +DirectShowOutputPin::~DirectShowOutputPin() +{ +} + +HRESULT DirectShowOutputPin::completeConnection(IPin *pin) +{ + if (!pin) + return E_POINTER; + + Q_ASSERT(m_inputPin == NULL); + Q_ASSERT(m_allocator == NULL); + + HRESULT hr = pin->QueryInterface(IID_PPV_ARGS(&m_inputPin)); + if (FAILED(hr)) + return hr; + + ALLOCATOR_PROPERTIES prop; + ZeroMemory(&prop, sizeof(prop)); + m_inputPin->GetAllocatorRequirements(&prop); + if (prop.cBuffers <= 0) + prop.cBuffers = 1; + if (prop.cbBuffer <= 0) + prop.cbBuffer = 1; + if (prop.cbAlign <= 0) + prop.cbAlign = 1; + + // Use the connected input pin's allocator if it has one + hr = m_inputPin->GetAllocator(&m_allocator); + if (SUCCEEDED(hr)) { + ALLOCATOR_PROPERTIES actualProperties; + hr = m_allocator->SetProperties(&prop, &actualProperties); + + if (SUCCEEDED(hr)) { + hr = m_inputPin->NotifyAllocator(m_allocator, FALSE); + if (SUCCEEDED(hr)) + return S_OK; + } + + m_allocator->Release(); + m_allocator = NULL; + } + + // Otherwise, allocate its own allocator + m_allocator = com_new(CLSID_MemoryAllocator); + if (!m_allocator) { + hr = E_OUTOFMEMORY; + } else { + ALLOCATOR_PROPERTIES actualProperties; + hr = m_allocator->SetProperties(&prop, &actualProperties); + + if (SUCCEEDED(hr)) { + hr = m_inputPin->NotifyAllocator(m_allocator, FALSE); + if (SUCCEEDED(hr)) + return S_OK; + } + + m_allocator->Release(); + m_allocator = NULL; + } + + return hr; +} + +HRESULT DirectShowOutputPin::connectionEnded() +{ + if (m_allocator) { + HRESULT hr = m_allocator->Decommit(); + if (FAILED(hr)) + return hr; + + m_allocator->Release(); + m_allocator = NULL; + } + + if (m_inputPin) { + m_inputPin->Release(); + m_inputPin = NULL; + } + + return S_OK; +} + +HRESULT DirectShowOutputPin::setActive(bool active) +{ + if (!m_allocator) + return VFW_E_NO_ALLOCATOR; + + return active ? m_allocator->Commit() + : m_allocator->Decommit(); +} + +HRESULT DirectShowOutputPin::EndOfStream() +{ + return E_UNEXPECTED; +} + + +/* DirectShowInputPin */ + +DirectShowInputPin::DirectShowInputPin(DirectShowBaseFilter *filter, const QString &name) + : DirectShowPin(filter, name, PINDIR_INPUT) + , m_allocator(NULL) + , m_flushing(false) + , m_inErrorState(false) +{ + ZeroMemory(&m_sampleProperties, sizeof(m_sampleProperties)); +} + +DirectShowInputPin::~DirectShowInputPin() +{ + +} + +HRESULT DirectShowInputPin::getInterface(const IID &riid, void **ppvObject) +{ + if (riid == IID_IMemInputPin) + return GetInterface(static_cast(this), ppvObject); + else + return DirectShowPin::getInterface(riid, ppvObject); +} + +HRESULT DirectShowInputPin::connectionEnded() +{ + if (m_allocator) { + HRESULT hr = m_allocator->Decommit(); + if (FAILED(hr)) + return hr; + + m_allocator->Release(); + m_allocator = NULL; + } + + return S_OK; +} + +HRESULT DirectShowInputPin::setActive(bool active) +{ + if (!active) { + m_inErrorState = false; + + if (!m_allocator) + return VFW_E_NO_ALLOCATOR; + + m_flushing = false; + return m_allocator->Decommit(); + } + + return S_OK; +} + +HRESULT DirectShowInputPin::EndOfStream() +{ + if (m_filter->state() == State_Stopped) + return VFW_E_WRONG_STATE; + if (m_flushing) + return S_FALSE; + if (m_inErrorState) + return VFW_E_RUNTIME_ERROR; + + return S_OK; +} + +HRESULT DirectShowInputPin::BeginFlush() +{ + QMutexLocker locker(&m_mutex); + m_flushing = true; + return S_OK; +} + +HRESULT DirectShowInputPin::EndFlush() +{ + QMutexLocker locker(&m_mutex); + m_flushing = false; + m_inErrorState = false; + return S_OK; +} + +HRESULT DirectShowInputPin::GetAllocator(IMemAllocator **ppAllocator) +{ + if (!ppAllocator) + return E_POINTER; + + QMutexLocker locker(&m_mutex); + + if (!m_allocator) { + m_allocator = com_new(CLSID_MemoryAllocator);; + if (!m_allocator) + return E_OUTOFMEMORY; + } + + *ppAllocator = m_allocator; + m_allocator->AddRef(); + + return S_OK; +} + +HRESULT DirectShowInputPin::NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly) +{ + Q_UNUSED(bReadOnly) + + if (!pAllocator) + return E_POINTER; + + QMutexLocker locker(&m_mutex); + + if (m_allocator) + m_allocator->Release(); + + m_allocator = pAllocator; + m_allocator->AddRef(); + + return S_OK; +} + +HRESULT DirectShowInputPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps) +{ + Q_UNUSED(pProps) + return E_NOTIMPL; +} + +HRESULT DirectShowInputPin::Receive(IMediaSample *pSample) +{ + if (!pSample) + return E_POINTER; + if (m_filter->state() == State_Stopped) + return VFW_E_WRONG_STATE; + if (m_flushing) + return S_FALSE; + if (m_inErrorState) + return VFW_E_RUNTIME_ERROR; + + HRESULT hr = S_OK; + + IMediaSample2 *sample2; + if (SUCCEEDED(pSample->QueryInterface(IID_PPV_ARGS(&sample2)))) { + hr = sample2->GetProperties(sizeof(m_sampleProperties), (PBYTE)&m_sampleProperties); + sample2->Release(); + if (FAILED(hr)) + return hr; + } else { + m_sampleProperties.cbData = sizeof(m_sampleProperties); + m_sampleProperties.dwTypeSpecificFlags = 0; + m_sampleProperties.dwStreamId = AM_STREAM_MEDIA; + m_sampleProperties.dwSampleFlags = 0; + if (pSample->IsDiscontinuity() == S_OK) + m_sampleProperties.dwSampleFlags |= AM_SAMPLE_DATADISCONTINUITY; + if (pSample->IsPreroll() == S_OK) + m_sampleProperties.dwSampleFlags |= AM_SAMPLE_PREROLL; + if (pSample->IsSyncPoint() == S_OK) + m_sampleProperties.dwSampleFlags |= AM_SAMPLE_SPLICEPOINT; + if (SUCCEEDED(pSample->GetTime(&m_sampleProperties.tStart, + &m_sampleProperties.tStop))) { + m_sampleProperties.dwSampleFlags |= AM_SAMPLE_TIMEVALID | AM_SAMPLE_STOPVALID; + } + if (pSample->GetMediaType(&m_sampleProperties.pMediaType) == S_OK) + m_sampleProperties.dwSampleFlags |= AM_SAMPLE_TYPECHANGED; + pSample->GetPointer(&m_sampleProperties.pbBuffer); + m_sampleProperties.lActual = pSample->GetActualDataLength(); + m_sampleProperties.cbBuffer = pSample->GetSize(); + } + + + if (!(m_sampleProperties.dwSampleFlags & AM_SAMPLE_TYPECHANGED)) + return S_OK; + + if (isMediaTypeSupported(m_sampleProperties.pMediaType)) + return S_OK; + + m_inErrorState = true; + EndOfStream(); + m_filter->NotifyEvent(EC_ERRORABORT, VFW_E_TYPE_NOT_ACCEPTED, 0); + return VFW_E_INVALIDMEDIATYPE; +} + +HRESULT DirectShowInputPin::ReceiveMultiple(IMediaSample **pSamples, long nSamples, long *nSamplesProcessed) +{ + if (!pSamples || !nSamplesProcessed) + return E_POINTER; + + HRESULT hr = S_OK; + *nSamplesProcessed = 0; + while (nSamples-- > 0) { + hr = Receive(pSamples[*nSamplesProcessed]); + if (hr != S_OK) + break; + (*nSamplesProcessed)++; + } + return hr; +} + +HRESULT DirectShowInputPin::ReceiveCanBlock() +{ + int outputPins = 0; + + const QList pinList = m_filter->pins(); + for (DirectShowPin *pin : pinList) { + PIN_DIRECTION pd; + HRESULT hr = pin->QueryDirection(&pd); + if (FAILED(hr)) + return hr; + + if (pd == PINDIR_OUTPUT) { + IPin *connected; + hr = pin->ConnectedTo(&connected); + if (SUCCEEDED(hr)) { + ++outputPins; + IMemInputPin *inputPin; + hr = connected->QueryInterface(IID_PPV_ARGS(&inputPin)); + connected->Release(); + if (SUCCEEDED(hr)) { + hr = inputPin->ReceiveCanBlock(); + inputPin->Release(); + if (hr != S_FALSE) + return S_OK; + } else { + return S_OK; + } + } + } + } + + return outputPins == 0 ? S_OK : S_FALSE; +} + +QT_END_NAMESPACE diff --git a/src/plugins/directshow/common/directshowpin.h b/src/plugins/directshow/common/directshowpin.h new file mode 100644 index 000000000..97e808384 --- /dev/null +++ b/src/plugins/directshow/common/directshowpin.h @@ -0,0 +1,192 @@ +/**************************************************************************** +** +** Copyright (C) 2017 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTSHOWPIN_H +#define DIRECTSHOWPIN_H + +#include "directshowobject.h" + +#include "directshowmediatype.h" +#include +#include + +QT_BEGIN_NAMESPACE + +class DirectShowBaseFilter; + +class DirectShowPin : public DirectShowObject + , public IPin +{ + DIRECTSHOW_OBJECT + +public: + virtual ~DirectShowPin(); + + QString name() const { return m_name; } + bool isConnected() const { return m_peerPin != NULL; } + + virtual bool isMediaTypeSupported(const AM_MEDIA_TYPE *type) = 0; + virtual QList supportedMediaTypes(); + virtual bool setMediaType(const AM_MEDIA_TYPE *type); + + virtual HRESULT completeConnection(IPin *pin); + virtual HRESULT connectionEnded(); + + virtual HRESULT setActive(bool active); + + // DirectShowObject + HRESULT getInterface(REFIID riid, void **ppvObject); + + // IPin + STDMETHODIMP Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt); + STDMETHODIMP ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt); + STDMETHODIMP Disconnect(); + STDMETHODIMP ConnectedTo(IPin **ppPin); + + STDMETHODIMP ConnectionMediaType(AM_MEDIA_TYPE *pmt); + + STDMETHODIMP QueryPinInfo(PIN_INFO *pInfo); + STDMETHODIMP QueryId(LPWSTR *Id); + + STDMETHODIMP QueryAccept(const AM_MEDIA_TYPE *pmt); + + STDMETHODIMP EnumMediaTypes(IEnumMediaTypes **ppEnum); + + STDMETHODIMP QueryInternalConnections(IPin **apPin, ULONG *nPin); + + STDMETHODIMP EndOfStream(); + + STDMETHODIMP BeginFlush(); + STDMETHODIMP EndFlush(); + + STDMETHODIMP NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate); + + STDMETHODIMP QueryDirection(PIN_DIRECTION *pPinDir); + +protected: + DirectShowPin(DirectShowBaseFilter *filter, const QString &name, PIN_DIRECTION direction); + + QMutex m_mutex; + + DirectShowBaseFilter *m_filter; + QString m_name; + PIN_DIRECTION m_direction; + + IPin *m_peerPin; + DirectShowMediaType m_mediaType; + +private: + Q_DISABLE_COPY(DirectShowPin) + HRESULT tryMediaTypes(IPin *pin, const AM_MEDIA_TYPE *type, IEnumMediaTypes *enumMediaTypes); + HRESULT tryConnect(IPin *pin, const AM_MEDIA_TYPE *type); +}; + + +class DirectShowOutputPin : public DirectShowPin +{ + DIRECTSHOW_OBJECT + +public: + virtual ~DirectShowOutputPin(); + + // DirectShowPin + virtual HRESULT completeConnection(IPin *pin); + virtual HRESULT connectionEnded(); + virtual HRESULT setActive(bool active); + + // IPin + STDMETHODIMP EndOfStream(); + +protected: + DirectShowOutputPin(DirectShowBaseFilter *filter, const QString &name); + + IMemAllocator *m_allocator; + IMemInputPin *m_inputPin; + +private: + Q_DISABLE_COPY(DirectShowOutputPin) +}; + + +class DirectShowInputPin : public DirectShowPin + , public IMemInputPin +{ + DIRECTSHOW_OBJECT + +public: + virtual ~DirectShowInputPin(); + + const AM_SAMPLE2_PROPERTIES *currentSampleProperties() const { return &m_sampleProperties; } + + // DirectShowObject + HRESULT getInterface(REFIID riid, void **ppvObject); + + // DirectShowPin + HRESULT connectionEnded(); + HRESULT setActive(bool active); + + // IPin + STDMETHODIMP EndOfStream(); + STDMETHODIMP BeginFlush(); + STDMETHODIMP EndFlush(); + + // IMemInputPin + STDMETHODIMP GetAllocator(IMemAllocator **ppAllocator); + STDMETHODIMP NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly); + STDMETHODIMP GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps); + + STDMETHODIMP Receive(IMediaSample *pSample); + STDMETHODIMP ReceiveMultiple(IMediaSample **pSamples, long nSamples, long *nSamplesProcessed); + STDMETHODIMP ReceiveCanBlock(); + +protected: + DirectShowInputPin(DirectShowBaseFilter *filter, const QString &name); + + IMemAllocator *m_allocator; + bool m_flushing; + bool m_inErrorState; + AM_SAMPLE2_PROPERTIES m_sampleProperties; + +private: + Q_DISABLE_COPY(DirectShowInputPin) +}; + +QT_END_NAMESPACE + +#endif // DIRECTSHOWPIN_H diff --git a/src/plugins/directshow/common/directshowpinenum.cpp b/src/plugins/directshow/common/directshowpinenum.cpp new file mode 100644 index 000000000..910bba77d --- /dev/null +++ b/src/plugins/directshow/common/directshowpinenum.cpp @@ -0,0 +1,130 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "directshowpinenum.h" +#include "directshowbasefilter.h" + +QT_BEGIN_NAMESPACE + +DirectShowPinEnum::DirectShowPinEnum(DirectShowBaseFilter *filter) + : m_filter(filter) + , m_index(0) +{ + m_filter->AddRef(); + const QList pinList = filter->pins(); + for (DirectShowPin *pin : pinList) { + pin->AddRef(); + m_pins.append(pin); + } +} + +DirectShowPinEnum::DirectShowPinEnum(const QList &pins) + : m_filter(NULL) + , m_pins(pins) + , m_index(0) +{ + for (IPin *pin : qAsConst(m_pins)) + pin->AddRef(); +} + +DirectShowPinEnum::~DirectShowPinEnum() +{ + for (IPin *pin : qAsConst(m_pins)) + pin->Release(); + if (m_filter) + m_filter->Release(); +} + +HRESULT DirectShowPinEnum::getInterface(REFIID riid, void **ppvObject) +{ + if (riid == IID_IEnumPins) { + return GetInterface(static_cast(this), ppvObject); + } else { + return DirectShowObject::getInterface(riid, ppvObject); + } +} + +HRESULT DirectShowPinEnum::Next(ULONG cPins, IPin **ppPins, ULONG *pcFetched) +{ + if (ppPins && (pcFetched || cPins == 1)) { + ULONG count = qBound(0, cPins, m_pins.count() - m_index); + + for (ULONG i = 0; i < count; ++i, ++m_index) { + ppPins[i] = m_pins.at(m_index); + ppPins[i]->AddRef(); + } + + if (pcFetched) + *pcFetched = count; + + return count == cPins ? S_OK : S_FALSE; + } else { + return E_POINTER; + } +} + +HRESULT DirectShowPinEnum::Skip(ULONG cPins) +{ + m_index = qMin(int(m_index + cPins), m_pins.count()); + + return m_index < m_pins.count() ? S_OK : S_FALSE; +} + +HRESULT DirectShowPinEnum::Reset() +{ + m_index = 0; + + return S_OK; +} + +HRESULT DirectShowPinEnum::Clone(IEnumPins **ppEnum) +{ + if (ppEnum) { + if (m_filter) + *ppEnum = new DirectShowPinEnum(m_filter); + else + *ppEnum = new DirectShowPinEnum(m_pins); + + return S_OK; + } else { + return E_POINTER; + } +} + +QT_END_NAMESPACE diff --git a/src/plugins/directshow/common/directshowpinenum.h b/src/plugins/directshow/common/directshowpinenum.h new file mode 100644 index 000000000..77214e376 --- /dev/null +++ b/src/plugins/directshow/common/directshowpinenum.h @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTSHOWPINENUM_H +#define DIRECTSHOWPINENUM_H + +#include + +#include +#include "directshowpin.h" + +QT_BEGIN_NAMESPACE + +class DirectShowBaseFilter; + +class DirectShowPinEnum : public DirectShowObject + , public IEnumPins +{ + DIRECTSHOW_OBJECT + +public: + DirectShowPinEnum(DirectShowBaseFilter *filter); + DirectShowPinEnum(const QList &pins); + ~DirectShowPinEnum(); + + // DirectShowObject + HRESULT getInterface(REFIID riid, void **ppvObject); + + // IEnumPins + STDMETHODIMP Next(ULONG cPins, IPin **ppPins, ULONG *pcFetched); + STDMETHODIMP Skip(ULONG cPins); + STDMETHODIMP Reset(); + STDMETHODIMP Clone(IEnumPins **ppEnum); + +private: + Q_DISABLE_COPY(DirectShowPinEnum) + + DirectShowBaseFilter *m_filter; + QList m_pins; + int m_index; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/directshow/common/directshowutils.cpp b/src/plugins/directshow/common/directshowutils.cpp new file mode 100644 index 000000000..96fabd6da --- /dev/null +++ b/src/plugins/directshow/common/directshowutils.cpp @@ -0,0 +1,313 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "directshowutils.h" + +QT_BEGIN_NAMESPACE + +/** + * @brief DirectShowUtils::isPinConnected + * @param pin + * @param hrOut + * @return + */ +bool DirectShowUtils::isPinConnected(IPin *pin, HRESULT *hrOut) +{ + IPin *connectedPin = nullptr; + const ScopedSafeRelease releasePin { &connectedPin }; + HRESULT hr = S_OK; + if (!hrOut) + hrOut = &hr; + + *hrOut = pin->ConnectedTo(&connectedPin); + if (*hrOut == VFW_E_NOT_CONNECTED) // Not an error in this case + *hrOut = S_OK; + + if (FAILED(*hrOut)) { + qCDebug(qtDirectShowPlugin, "Querying pin connection failed!"); + return false; + } + + return true; +} + +/** + * @brief DirectShowUtils::hasPinDirection + * @param pin + * @param direction + * @param hrOut + * @return + */ +bool DirectShowUtils::hasPinDirection(IPin *pin, PIN_DIRECTION direction, HRESULT *hrOut) +{ + PIN_DIRECTION pinDir; + HRESULT hr = S_OK; + if (!hrOut) + hrOut = &hr; + + *hrOut = pin->QueryDirection(&pinDir); + + if (FAILED(*hrOut)) { + qCDebug(qtDirectShowPlugin, "Querying pin direction failed!"); + return false; + } + + return (pinDir == direction); +} + +/** + * @brief DirectShowUtils::getPin + * @param filter + * @param pinDirection + * @param pin + * @param hrOut + * @return + */ +bool DirectShowUtils::getPin(IBaseFilter *filter, PIN_DIRECTION pinDirection, IPin **pin, HRESULT *hrOut) +{ + IEnumPins *enumPins = nullptr; + const ScopedSafeRelease releaseEnumPins { &enumPins }; + HRESULT hr S_OK; + if (!hrOut) + hrOut = &hr; + + *hrOut = filter->EnumPins(&enumPins); + if (FAILED(*hrOut)) { + qCDebug(qtDirectShowPlugin, "Unable to retrieve pins from the filter!"); + return false; + } + + enumPins->Reset(); + IPin *nextPin = nullptr; + while (enumPins->Next(1, &nextPin, NULL) == S_OK) { + const ScopedSafeRelease releasePin { &nextPin }; + PIN_DIRECTION currentPinDir; + *hrOut = nextPin->QueryDirection(¤tPinDir); + if (currentPinDir == pinDirection) { + *pin = nextPin; + (*pin)->AddRef(); + return true; + } + } + + return false; +} + +/** + * @brief DirectShowUtils::matchPin + * @param pin + * @param pinDirection + * @param shouldBeConnected + * @param hrOut + * @return + */ +bool DirectShowUtils::matchPin(IPin *pin, PIN_DIRECTION pinDirection, BOOL shouldBeConnected, HRESULT *hrOut) +{ + HRESULT hr = S_OK; + if (!hrOut) + hrOut = &hr; + + const BOOL isConnected = isPinConnected(pin, hrOut); + if (FAILED(*hrOut)) // Error reason will already be logged, so just return. + return false; + + if (isConnected == shouldBeConnected) + return hasPinDirection(pin, pinDirection, hrOut); + + return SUCCEEDED(*hrOut); +} + +/** + * @brief DirectShowUtils::findUnconnectedPin + * @param filter + * @param pinDirection + * @param pin + * @param hrOut + * @return + */ +bool DirectShowUtils::findUnconnectedPin(IBaseFilter *filter, PIN_DIRECTION pinDirection, IPin **pin, HRESULT *hrOut) +{ + HRESULT hr = S_OK; + if (!hrOut) + hrOut = &hr; + + IEnumPins *enumPins = nullptr; + const ScopedSafeRelease releaseEnumPins { &enumPins }; + *hrOut = filter->EnumPins(&enumPins); + if (FAILED(*hrOut)) { + qCDebug(qtDirectShowPlugin, "Unable to retrieve pins from the DS filter"); + return false; + } + + IPin *nextPin = nullptr; + while (S_OK == enumPins->Next(1, &nextPin, nullptr)) { + const ScopedSafeRelease releaseNextPin { &nextPin }; + if (matchPin(nextPin, pinDirection, FALSE, hrOut)) { + *pin = nextPin; + (*pin)->AddRef(); + return true; + } + + if (FAILED(*hrOut)) + return false; + } + + qCDebug(qtDirectShowPlugin, "No unconnected pins found"); + *hrOut = VFW_E_NOT_FOUND; + + return false; +} + +/** + * @brief DirectShowUtils::connectFilters - Attempts to connect \a outputPin to \a filter + * @param graph + * @param outputPin + * @param filter + * @param hrOut + * @return + */ +bool DirectShowUtils::connectFilters(IGraphBuilder *graph, IPin *outputPin, IBaseFilter *filter, HRESULT *hrOut) +{ + + // Find an input pin on the downstream filter. + HRESULT hr = S_OK; + if (!hrOut) + hrOut = &hr; + + IPin *inputPin = nullptr; + const ScopedSafeRelease releaseInputPin { &inputPin }; + if (!findUnconnectedPin(filter, PINDIR_INPUT, &inputPin, hrOut)) + return false; + + + // Try to connect them. + *hrOut = graph->Connect(outputPin, inputPin); + if (FAILED(*hrOut)) { + qCDebug(qtDirectShowPlugin, "Unable to connect output pin to filter!"); + return false; + } + + return true; +} + +/** + * @brief DirectShowUtils::connectFilters - Attempts to connect \a filter to \a inputPin. + * @param graph + * @param filter + * @param inputPin + * @param hrOut + * @return + */ +bool DirectShowUtils::connectFilters(IGraphBuilder *graph, IBaseFilter *filter, IPin *inputPin, HRESULT *hrOut) +{ + HRESULT hr = S_OK; + if (!hrOut) + hrOut = &hr; + + IPin *outputPin = nullptr; + const ScopedSafeRelease releaseOutputPin { &outputPin }; + // Find an output pin on the upstream filter. + if (findUnconnectedPin(filter, PINDIR_OUTPUT, &outputPin, hrOut)) + return false; + + *hrOut = graph->Connect(outputPin, inputPin); + if (FAILED(*hrOut)) { + qCDebug(qtDirectShowPlugin, "Unable to connect filter to input pin!"); + return false; + } + + return true; +} + +/** + * @brief DirectShowUtils::connectFilters - Attempts to connect the \a upstreamFilter to \a downstreamFilter. + * @param graph + * @param upstreamFilter + * @param downstreamFilter + * @param autoConnect - If set to true all filters in the graph will be considered. + * @param hrOut + * @return true if the the filters were connected, false otherwise. + */ +bool DirectShowUtils::connectFilters(IGraphBuilder *graph, + IBaseFilter *upstreamFilter, + IBaseFilter *downstreamFilter, + bool autoConnect, + HRESULT *hrOut) +{ + HRESULT hr = S_OK; + if (!hrOut) + hrOut = &hr; + + const auto findAndConnect = [graph, downstreamFilter, hrOut](IBaseFilter *filter) -> bool { + IPin *outputPin = nullptr; + const ScopedSafeRelease releaseOutputPin { &outputPin }; + if (findUnconnectedPin(filter, PINDIR_OUTPUT, &outputPin, hrOut)) + return connectFilters(graph, outputPin, downstreamFilter, hrOut); + + return false; + }; + + // Try to connect to the upstream filter first. + if (findAndConnect(upstreamFilter)) + return S_OK; + + const auto getFilters = [graph, hrOut]() -> IEnumFilters * { + IEnumFilters *f = nullptr; + *hrOut = graph->EnumFilters(&f); + return f; + }; + IEnumFilters *filters = autoConnect ? getFilters() + : nullptr; + const ScopedSafeRelease releaseEnumFilters { &filters }; + if (!filters) { + qCDebug(qtDirectShowPlugin, "No filters found!"); + return false; + } + + IBaseFilter *nextFilter = nullptr; + while (S_OK == filters->Next(1, &nextFilter, 0)) { + const ScopedSafeRelease releaseNextFilter { &nextFilter }; + if (nextFilter && findAndConnect(nextFilter)) + break; + } + + return SUCCEEDED(*hrOut); +} + +QT_END_NAMESPACE diff --git a/src/plugins/directshow/common/directshowutils.h b/src/plugins/directshow/common/directshowutils.h new file mode 100644 index 000000000..09c81c257 --- /dev/null +++ b/src/plugins/directshow/common/directshowutils.h @@ -0,0 +1,87 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTSHOWUTILS_H +#define DIRECTSHOWUTILS_H + +#include "directshowglobal.h" + +QT_BEGIN_NAMESPACE + +namespace DirectShowUtils +{ +template +void safeRelease(T **iface) { + if (!iface) + return; + + if (!*iface) + return; + + (*iface)->Release(); + *iface = nullptr; +} + +template +struct ScopedSafeRelease +{ + T **iunknown; + ~ScopedSafeRelease() + { + DirectShowUtils::safeRelease(iunknown); + } +}; + +bool getPin(IBaseFilter *filter, PIN_DIRECTION pinDirection, IPin **pin, HRESULT *hrOut); +bool isPinConnected(IPin *pin, HRESULT *hrOut = nullptr); +bool hasPinDirection(IPin *pin, PIN_DIRECTION direction, HRESULT *hrOut = nullptr); +bool matchPin(IPin *pin, PIN_DIRECTION pinDirection, BOOL shouldBeConnected, HRESULT *hrOut = nullptr); +bool findUnconnectedPin(IBaseFilter *filter, PIN_DIRECTION pinDirection, IPin **pin, HRESULT *hrOut = nullptr); +bool connectFilters(IGraphBuilder *graph, IPin *outputPin, IBaseFilter *filter, HRESULT *hrOut = nullptr); +bool connectFilters(IGraphBuilder *graph, IBaseFilter *filter, IPin *inputPin, HRESULT *hrOut = nullptr); +bool connectFilters(IGraphBuilder *graph, + IBaseFilter *upstreamFilter, + IBaseFilter *downstreamFilter, + bool autoConnect = false, + HRESULT *hrOut = nullptr); +} + +QT_END_NAMESPACE + +#endif // DIRECTSHOWUTILS_H diff --git a/src/plugins/directshow/common/directshowvideobuffer.cpp b/src/plugins/directshow/common/directshowvideobuffer.cpp new file mode 100644 index 000000000..7f94da97e --- /dev/null +++ b/src/plugins/directshow/common/directshowvideobuffer.cpp @@ -0,0 +1,88 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "directshowvideobuffer.h" + +QT_BEGIN_NAMESPACE + +DirectShowVideoBuffer::DirectShowVideoBuffer(IMediaSample *sample, int bytesPerLine) + : QAbstractVideoBuffer(NoHandle) + , m_sample(sample) + , m_bytesPerLine(bytesPerLine) + , m_mapMode(NotMapped) +{ + m_sample->AddRef(); +} + +DirectShowVideoBuffer::~DirectShowVideoBuffer() +{ + m_sample->Release(); +} + +uchar *DirectShowVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine) +{ + if (m_mapMode == NotMapped && mode != NotMapped) { + if (numBytes) + *numBytes = m_sample->GetActualDataLength(); + + if (bytesPerLine) + *bytesPerLine = m_bytesPerLine; + + BYTE *bytes = 0; + + if (m_sample->GetPointer(&bytes) == S_OK) { + m_mapMode = mode; + + return reinterpret_cast(bytes); + } + } + return 0; +} + +void DirectShowVideoBuffer::unmap() +{ + m_mapMode = NotMapped; +} + +QAbstractVideoBuffer::MapMode DirectShowVideoBuffer::mapMode() const +{ + return m_mapMode; +} + +QT_END_NAMESPACE diff --git a/src/plugins/directshow/common/directshowvideobuffer.h b/src/plugins/directshow/common/directshowvideobuffer.h new file mode 100644 index 000000000..85e02b53d --- /dev/null +++ b/src/plugins/directshow/common/directshowvideobuffer.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or (at your option) the GNU General +** Public license version 3 or any later version approved by the KDE Free +** Qt Foundation. The licenses are as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-2.0.html and +** https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef DIRECTSHOWVIDEOBUFFER_H +#define DIRECTSHOWVIDEOBUFFER_H + +#include + +#include + +QT_BEGIN_NAMESPACE + +class DirectShowVideoBuffer : public QAbstractVideoBuffer +{ +public: + DirectShowVideoBuffer(IMediaSample *sample, int bytesPerLine); + ~DirectShowVideoBuffer(); + + IMediaSample *sample() { return m_sample; } + + uchar *map(MapMode mode, int *numBytes, int *bytesPerLine); + void unmap(); + + MapMode mapMode() const; + +private: + IMediaSample *m_sample; + int m_bytesPerLine; + MapMode m_mapMode; +}; + +QT_END_NAMESPACE + +#endif diff --git a/src/plugins/directshow/directshow.pro b/src/plugins/directshow/directshow.pro index 35301474f..2857f87d9 100644 --- a/src/plugins/directshow/directshow.pro +++ b/src/plugins/directshow/directshow.pro @@ -11,7 +11,6 @@ SOURCES += dsserviceplugin.cpp mingw: DEFINES += NO_DSHOW_STRSAFE include(common/common.pri) -include(helpers/helpers.pri) qtConfig(directshow-player): include(player/player.pri) include(camera/camera.pri) diff --git a/src/plugins/directshow/helpers/directshowbasefilter.cpp b/src/plugins/directshow/helpers/directshowbasefilter.cpp deleted file mode 100644 index 342f0c271..000000000 --- a/src/plugins/directshow/helpers/directshowbasefilter.cpp +++ /dev/null @@ -1,277 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowbasefilter.h" - -#include "directshowpinenum.h" - -QT_BEGIN_NAMESPACE - -DirectShowBaseFilter::DirectShowBaseFilter() - : m_mutex(QMutex::Recursive) - , m_state(State_Stopped) - , m_graph(NULL) - , m_clock(NULL) - , m_sink(NULL) -{ - -} - -DirectShowBaseFilter::~DirectShowBaseFilter() -{ - if (m_clock) { - m_clock->Release(); - m_clock = NULL; - } -} - -HRESULT DirectShowBaseFilter::getInterface(REFIID riid, void **ppvObject) -{ - if (riid == IID_IPersist - || riid == IID_IMediaFilter - || riid == IID_IBaseFilter) { - return GetInterface(static_cast(this), ppvObject); - } else { - return DirectShowObject::getInterface(riid, ppvObject); - } -} - -HRESULT DirectShowBaseFilter::GetClassID(CLSID *pClassID) -{ - *pClassID = CLSID_NULL; - return S_OK; -} - -HRESULT DirectShowBaseFilter::NotifyEvent(long eventCode, LONG_PTR eventParam1, LONG_PTR eventParam2) -{ - IMediaEventSink *sink = m_sink; - if (sink) { - if (eventCode == EC_COMPLETE) - eventParam2 = (LONG_PTR)(IBaseFilter*)this; - - return sink->Notify(eventCode, eventParam1, eventParam2); - } else { - return E_NOTIMPL; - } -} - -HRESULT DirectShowBaseFilter::Run(REFERENCE_TIME tStart) -{ - Q_UNUSED(tStart) - QMutexLocker locker(&m_mutex); - - m_startTime = tStart; - - if (m_state == State_Stopped){ - HRESULT hr = Pause(); - if (FAILED(hr)) - return hr; - } - - m_state = State_Running; - - return S_OK; -} - -HRESULT DirectShowBaseFilter::Pause() -{ - QMutexLocker locker(&m_mutex); - - if (m_state == State_Stopped) { - const QList pinList = pins(); - for (DirectShowPin *pin : pinList) { - if (pin->isConnected()) { - HRESULT hr = pin->setActive(true); - if (FAILED(hr)) - return hr; - } - } - } - - m_state = State_Paused; - - return S_OK; -} - -HRESULT DirectShowBaseFilter::Stop() -{ - QMutexLocker locker(&m_mutex); - - HRESULT hr = S_OK; - - if (m_state != State_Stopped) { - const QList pinList = pins(); - for (DirectShowPin *pin : pinList) { - if (pin->isConnected()) { - HRESULT hrTmp = pin->setActive(false); - if (FAILED(hrTmp) && SUCCEEDED(hr)) - hr = hrTmp; - } - } - } - - m_state = State_Stopped; - - return hr; -} - -HRESULT DirectShowBaseFilter::GetState(DWORD dwMilliSecsTimeout, FILTER_STATE *pState) -{ - Q_UNUSED(dwMilliSecsTimeout); - - if (!pState) { - return E_POINTER; - } else { - QMutexLocker locker(&m_mutex); - - *pState = m_state; - - return S_OK; - } -} - -HRESULT DirectShowBaseFilter::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 DirectShowBaseFilter::GetSyncSource(IReferenceClock **ppClock) -{ - if (!ppClock) { - return E_POINTER; - } else { - if (!m_clock) { - *ppClock = 0; - - return S_FALSE; - } else { - m_clock->AddRef(); - - *ppClock = m_clock; - - return S_OK; - } - } -} - -HRESULT DirectShowBaseFilter::EnumPins(IEnumPins **ppEnum) -{ - if (!ppEnum) { - return E_POINTER; - } else { - *ppEnum = new DirectShowPinEnum(this); - return S_OK; - } -} - -HRESULT DirectShowBaseFilter::FindPin(LPCWSTR Id, IPin **ppPin) -{ - if (!ppPin || !Id) { - return E_POINTER; - } else { - QMutexLocker locker(&m_mutex); - const QList pinList = pins(); - for (DirectShowPin *pin : pinList) { - if (QString::fromWCharArray(Id) == pin->name()) { - pin->AddRef(); - *ppPin = pin; - return S_OK; - } - } - - *ppPin = 0; - return VFW_E_NOT_FOUND; - } -} - -HRESULT DirectShowBaseFilter::JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName) -{ - QMutexLocker locker(&m_mutex); - - m_filterName = QString::fromWCharArray(pName); - m_graph = pGraph; - m_sink = NULL; - - if (m_graph) { - if (SUCCEEDED(m_graph->QueryInterface(IID_PPV_ARGS(&m_sink)))) - m_sink->Release(); // we don't keep a reference on it - } - - return S_OK; -} - -HRESULT DirectShowBaseFilter::QueryFilterInfo(FILTER_INFO *pInfo) -{ - if (!pInfo) { - return E_POINTER; - } else { - QString name = m_filterName; - - if (name.length() >= MAX_FILTER_NAME) - name.truncate(MAX_FILTER_NAME - 1); - - int length = name.toWCharArray(pInfo->achName); - pInfo->achName[length] = '\0'; - - if (m_graph) - m_graph->AddRef(); - - pInfo->pGraph = m_graph; - - return S_OK; - } -} - -HRESULT DirectShowBaseFilter::QueryVendorInfo(LPWSTR *pVendorInfo) -{ - Q_UNUSED(pVendorInfo); - return E_NOTIMPL; -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/helpers/directshowbasefilter.h b/src/plugins/directshow/helpers/directshowbasefilter.h deleted file mode 100644 index 9a2f44567..000000000 --- a/src/plugins/directshow/helpers/directshowbasefilter.h +++ /dev/null @@ -1,101 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWBASEFILTER_H -#define DIRECTSHOWBASEFILTER_H - -#include "directshowpin.h" - -QT_BEGIN_NAMESPACE - -class DirectShowBaseFilter : public DirectShowObject - , public IBaseFilter -{ - DIRECTSHOW_OBJECT - -public: - DirectShowBaseFilter(); - virtual ~DirectShowBaseFilter(); - - FILTER_STATE state() const { return m_state; } - HRESULT NotifyEvent(long eventCode, LONG_PTR eventParam1, LONG_PTR eventParam2); - - virtual QList pins() = 0; - - // DirectShowObject - HRESULT getInterface(const IID &riid, void **ppvObject); - - // IPersist - STDMETHODIMP GetClassID(CLSID *pClassID); - - // IMediaFilter - STDMETHODIMP Run(REFERENCE_TIME tStart); - STDMETHODIMP Pause(); - STDMETHODIMP Stop(); - - STDMETHODIMP GetState(DWORD dwMilliSecsTimeout, FILTER_STATE *pState); - - STDMETHODIMP SetSyncSource(IReferenceClock *pClock); - STDMETHODIMP GetSyncSource(IReferenceClock **ppClock); - - // IBaseFilter - STDMETHODIMP EnumPins(IEnumPins **ppEnum); - STDMETHODIMP FindPin(LPCWSTR Id, IPin **ppPin); - - STDMETHODIMP JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName); - - STDMETHODIMP QueryFilterInfo(FILTER_INFO *pInfo); - STDMETHODIMP QueryVendorInfo(LPWSTR *pVendorInfo); - -protected: - QMutex m_mutex; - FILTER_STATE m_state; - IFilterGraph *m_graph; - IReferenceClock *m_clock; - IMediaEventSink *m_sink; - QString m_filterName; - REFERENCE_TIME m_startTime; - -private: - Q_DISABLE_COPY(DirectShowBaseFilter) -}; - -QT_END_NAMESPACE - -#endif // DIRECTSHOWBASEFILTER_H diff --git a/src/plugins/directshow/helpers/directshoweventloop.cpp b/src/plugins/directshow/helpers/directshoweventloop.cpp deleted file mode 100644 index ef85c0429..000000000 --- a/src/plugins/directshow/helpers/directshoweventloop.cpp +++ /dev/null @@ -1,152 +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 - -#include -#include - -QT_BEGIN_NAMESPACE - -class DirectShowPostedEvent -{ -public: - DirectShowPostedEvent(QObject *receiver, QEvent *event) - : receiver(receiver) - , event(event) - , next(0) - { - } - - ~DirectShowPostedEvent() - { - delete event; - } - - QObject *receiver; - QEvent *event; - DirectShowPostedEvent *next; -}; - -DirectShowEventLoop::DirectShowEventLoop(QObject *parent) - : QObject(parent) - , m_postsHead(0) - , m_postsTail(0) - , m_eventHandle(::CreateEvent(0, 0, 0, 0)) - , m_waitHandle(::CreateEvent(0, 0, 0, 0)) -{ -} - -DirectShowEventLoop::~DirectShowEventLoop() -{ - ::CloseHandle(m_eventHandle); - ::CloseHandle(m_waitHandle); - - for (DirectShowPostedEvent *post = m_postsHead; post; post = m_postsHead) { - m_postsHead = m_postsHead->next; - - delete post; - } -} - -void DirectShowEventLoop::wait(QMutex *mutex) -{ - ::ResetEvent(m_waitHandle); - - mutex->unlock(); - - HANDLE handles[] = { m_eventHandle, m_waitHandle }; - while (::WaitForMultipleObjects(2, handles, false, INFINITE) == WAIT_OBJECT_0) - processEvents(); - - mutex->lock(); -} - -void DirectShowEventLoop::wake() -{ - ::SetEvent(m_waitHandle); -} - -void DirectShowEventLoop::postEvent(QObject *receiver, QEvent *event) -{ - QMutexLocker locker(&m_mutex); - - DirectShowPostedEvent *post = new DirectShowPostedEvent(receiver, event); - - if (m_postsTail) - m_postsTail->next = post; - else - m_postsHead = post; - - m_postsTail = post; - - QCoreApplication::postEvent(this, new QEvent(QEvent::User)); - ::SetEvent(m_eventHandle); -} - -void DirectShowEventLoop::customEvent(QEvent *event) -{ - if (event->type() == QEvent::User) { - processEvents(); - } else { - QObject::customEvent(event); - } -} - -void DirectShowEventLoop::processEvents() -{ - QMutexLocker locker(&m_mutex); - - ::ResetEvent(m_eventHandle); - - while(m_postsHead) { - DirectShowPostedEvent *post = m_postsHead; - m_postsHead = m_postsHead->next; - - if (!m_postsHead) - m_postsTail = 0; - - locker.unlock(); - QCoreApplication::sendEvent(post->receiver, post->event); - delete post; - locker.relock(); - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/helpers/directshoweventloop.h b/src/plugins/directshow/helpers/directshoweventloop.h deleted file mode 100644 index 609e53134..000000000 --- a/src/plugins/directshow/helpers/directshoweventloop.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWEVENTLOOP_H -#define DIRECTSHOWEVENTLOOP_H - -#include -#include -#include - -#include - -QT_BEGIN_NAMESPACE - -class DirectShowPostedEvent; - -class DirectShowEventLoop : public QObject -{ - Q_OBJECT -public: - DirectShowEventLoop(QObject *parent = 0); - ~DirectShowEventLoop(); - - void wait(QMutex *mutex); - void wake(); - - void postEvent(QObject *object, QEvent *event); - -protected: - void customEvent(QEvent *event); - -private: - void processEvents(); - - DirectShowPostedEvent *m_postsHead; - DirectShowPostedEvent *m_postsTail; - HANDLE m_eventHandle; - HANDLE m_waitHandle; - QMutex m_mutex; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/directshow/helpers/directshowglobal.h b/src/plugins/directshow/helpers/directshowglobal.h deleted file mode 100644 index 5f391710e..000000000 --- a/src/plugins/directshow/helpers/directshowglobal.h +++ /dev/null @@ -1,160 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWGLOBAL_H -#define DIRECTSHOWGLOBAL_H - -#include - -#include -#include - -QT_BEGIN_NAMESPACE - -Q_DECLARE_LOGGING_CATEGORY(qtDirectShowPlugin) - -QT_END_NAMESPACE - -template T *com_cast(IUnknown *unknown, const IID &iid) -{ - T *iface = 0; - return unknown && unknown->QueryInterface(iid, reinterpret_cast(&iface)) == S_OK - ? iface - : 0; -} - -template T *com_new(const IID &clsid) -{ - T *object = 0; - return CoCreateInstance( - clsid, - NULL, - CLSCTX_INPROC_SERVER, - IID_PPV_ARGS(&object)) == S_OK - ? object - : 0; -} - -template T *com_new(const IID &clsid, const IID &iid) -{ - T *object = 0; - return CoCreateInstance( - clsid, - NULL, - CLSCTX_INPROC_SERVER, - iid, - reinterpret_cast(&object)) == S_OK - ? object - : 0; -} - -DEFINE_GUID(MEDIASUBTYPE_I420, - 0x30323449,0x0000,0x0010,0x80,0x00,0x00,0xAA,0x00,0x38,0x9B,0x71); - -#ifndef __IFilterGraph2_INTERFACE_DEFINED__ -#define __IFilterGraph2_INTERFACE_DEFINED__ -#define INTERFACE IFilterGraph2 -DECLARE_INTERFACE_(IFilterGraph2 ,IGraphBuilder) -{ - STDMETHOD(AddSourceFilterForMoniker)(THIS_ IMoniker *, IBindCtx *, LPCWSTR,IBaseFilter **) PURE; - STDMETHOD(ReconnectEx)(THIS_ IPin *, const AM_MEDIA_TYPE *) PURE; - STDMETHOD(RenderEx)(IPin *, DWORD, DWORD *) PURE; -}; -#undef INTERFACE -#endif - -#ifndef __IAMFilterMiscFlags_INTERFACE_DEFINED__ -#define __IAMFilterMiscFlags_INTERFACE_DEFINED__ -#define INTERFACE IAMFilterMiscFlags -DECLARE_INTERFACE_(IAMFilterMiscFlags ,IUnknown) -{ - STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - STDMETHOD_(ULONG,GetMiscFlags)(THIS) PURE; -}; -#undef INTERFACE -#endif - -#ifndef __IFileSourceFilter_INTERFACE_DEFINED__ -#define __IFileSourceFilter_INTERFACE_DEFINED__ -#define INTERFACE IFileSourceFilter -DECLARE_INTERFACE_(IFileSourceFilter ,IUnknown) -{ - STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - STDMETHOD(Load)(THIS_ LPCOLESTR, const AM_MEDIA_TYPE *) PURE; - STDMETHOD(GetCurFile)(THIS_ LPOLESTR *ppszFileName, AM_MEDIA_TYPE *) PURE; -}; -#undef INTERFACE -#endif - -#ifndef __IAMOpenProgress_INTERFACE_DEFINED__ -#define __IAMOpenProgress_INTERFACE_DEFINED__ -#undef INTERFACE -#define INTERFACE IAMOpenProgress -DECLARE_INTERFACE_(IAMOpenProgress ,IUnknown) -{ - STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - STDMETHOD(QueryProgress)(THIS_ LONGLONG *, LONGLONG *) PURE; - STDMETHOD(AbortOperation)(THIS) PURE; -}; -#undef INTERFACE -#endif - -#ifndef __IFilterChain_INTERFACE_DEFINED__ -#define __IFilterChain_INTERFACE_DEFINED__ -#define INTERFACE IFilterChain -DECLARE_INTERFACE_(IFilterChain ,IUnknown) -{ - STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - STDMETHOD(StartChain)(IBaseFilter *, IBaseFilter *) PURE; - STDMETHOD(PauseChain)(IBaseFilter *, IBaseFilter *) PURE; - STDMETHOD(StopChain)(IBaseFilter *, IBaseFilter *) PURE; - STDMETHOD(RemoveChain)(IBaseFilter *, IBaseFilter *) PURE; -}; -#undef INTERFACE -#endif - -#endif diff --git a/src/plugins/directshow/helpers/directshowmediatype.cpp b/src/plugins/directshow/helpers/directshowmediatype.cpp deleted file mode 100644 index 65882806c..000000000 --- a/src/plugins/directshow/helpers/directshowmediatype.cpp +++ /dev/null @@ -1,350 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowmediatype.h" -#include "directshowglobal.h" - -namespace -{ - struct TypeLookup - { - QVideoFrame::PixelFormat pixelFormat; - GUID mediaType; - }; - - static const TypeLookup qt_typeLookup[] = - { - { QVideoFrame::Format_ARGB32, MEDIASUBTYPE_ARGB32 }, - { QVideoFrame::Format_RGB32, MEDIASUBTYPE_RGB32 }, - { QVideoFrame::Format_RGB24, MEDIASUBTYPE_RGB24 }, - { QVideoFrame::Format_RGB565, MEDIASUBTYPE_RGB565 }, - { QVideoFrame::Format_RGB555, MEDIASUBTYPE_RGB555 }, - { QVideoFrame::Format_AYUV444, MEDIASUBTYPE_AYUV }, - { QVideoFrame::Format_YUYV, MEDIASUBTYPE_YUY2 }, - { QVideoFrame::Format_UYVY, MEDIASUBTYPE_UYVY }, - { QVideoFrame::Format_IMC1, MEDIASUBTYPE_IMC1 }, - { QVideoFrame::Format_IMC2, MEDIASUBTYPE_IMC2 }, - { QVideoFrame::Format_IMC3, MEDIASUBTYPE_IMC3 }, - { QVideoFrame::Format_IMC4, MEDIASUBTYPE_IMC4 }, - { QVideoFrame::Format_YV12, MEDIASUBTYPE_YV12 }, - { QVideoFrame::Format_NV12, MEDIASUBTYPE_NV12 }, - { QVideoFrame::Format_YUV420P, MEDIASUBTYPE_IYUV }, - { QVideoFrame::Format_YUV420P, MEDIASUBTYPE_I420 }, - { QVideoFrame::Format_Jpeg, MEDIASUBTYPE_MJPG } - }; -} - -bool DirectShowMediaType::isPartiallySpecified(const AM_MEDIA_TYPE *mediaType) -{ - return mediaType->majortype == GUID_NULL || mediaType->formattype == GUID_NULL; -} - -DirectShowMediaType::DirectShowMediaType() - : mediaType({ GUID_NULL, GUID_NULL, TRUE, FALSE, 1, GUID_NULL, nullptr, 0, nullptr}) -{ -} - -DirectShowMediaType::DirectShowMediaType(const AM_MEDIA_TYPE &type) - : DirectShowMediaType() -{ - copy(&mediaType, &type); -} - -DirectShowMediaType::DirectShowMediaType(AM_MEDIA_TYPE &&type) - : DirectShowMediaType() -{ - move(&mediaType, type); -} - -DirectShowMediaType::DirectShowMediaType(const DirectShowMediaType &other) - : DirectShowMediaType() -{ - copy(&mediaType, &other.mediaType); -} - -DirectShowMediaType::DirectShowMediaType(DirectShowMediaType &&other) - : DirectShowMediaType() -{ - move(&mediaType, other.mediaType); -} - -DirectShowMediaType &DirectShowMediaType::operator=(const DirectShowMediaType &other) -{ - copy(&mediaType, &other.mediaType); - return *this; -} - -DirectShowMediaType &DirectShowMediaType::operator=(DirectShowMediaType &&other) -{ - move(&mediaType, other.mediaType); - return *this; -} - -void DirectShowMediaType::init(AM_MEDIA_TYPE *type) -{ - Q_ASSERT(type); - SecureZeroMemory(reinterpret_cast(type), sizeof(AM_MEDIA_TYPE)); - type->lSampleSize = 1; - type->bFixedSizeSamples = TRUE; -} - -void DirectShowMediaType::copy(AM_MEDIA_TYPE *target, const AM_MEDIA_TYPE *source) -{ - if (!(target && source)) - return; - - if (target == source) - return; - - clear(*target); - - copyToUninitialized(target, source); -} - -void DirectShowMediaType::copyToUninitialized(AM_MEDIA_TYPE *target, const AM_MEDIA_TYPE *source) -{ - *target = *source; - - if (source->cbFormat > 0) { - target->pbFormat = reinterpret_cast(CoTaskMemAlloc(source->cbFormat)); - memcpy(target->pbFormat, source->pbFormat, source->cbFormat); - } - if (target->pUnk) - target->pUnk->AddRef(); -} - -void DirectShowMediaType::move(AM_MEDIA_TYPE *target, AM_MEDIA_TYPE **source) -{ - if (!target || !source || !(*source)) - return; - - if (target == *source) - return; - - clear(*target); - *target = *(*source); - SecureZeroMemory(reinterpret_cast(*source), sizeof(AM_MEDIA_TYPE)); - *source = nullptr; -} - -void DirectShowMediaType::move(AM_MEDIA_TYPE *target, AM_MEDIA_TYPE &source) -{ - AM_MEDIA_TYPE *srcPtr = &source; - move(target, &srcPtr); -} - -/** - * @brief DirectShowMediaType::deleteType - Used for AM_MEDIA_TYPE structures that have - * been allocated by CoTaskMemAlloc or CreateMediaType. - * @param type - */ -void DirectShowMediaType::deleteType(AM_MEDIA_TYPE *type) -{ - if (!type) - return; - - clear(*type); - CoTaskMemFree(type); -} - -bool DirectShowMediaType::isCompatible(const AM_MEDIA_TYPE *a, const AM_MEDIA_TYPE *b) -{ - if (b->majortype != GUID_NULL && a->majortype != b->majortype) - return false; - - if (b->subtype != GUID_NULL && a->subtype != b->subtype) - return false; - - if (b->formattype != GUID_NULL) { - if (a->formattype != b->formattype) - return false; - if (a->cbFormat != b->cbFormat) - return false; - if (a->cbFormat != 0 && memcmp(a->pbFormat, b->pbFormat, a->cbFormat) != 0) - return false; - } - - return true; -} - -/** - * @brief DirectShowMediaType::clear - Clears all member data, and releases allocated buffers. - * Use this to release automatic AM_MEDIA_TYPE structures. - * @param type - */ -void DirectShowMediaType::clear(AM_MEDIA_TYPE &type) -{ - if (type.cbFormat > 0) - CoTaskMemFree(type.pbFormat); - - if (type.pUnk) - type.pUnk->Release(); - - SecureZeroMemory(&type, sizeof(type)); -} - - -GUID DirectShowMediaType::convertPixelFormat(QVideoFrame::PixelFormat format) -{ - const int count = sizeof(qt_typeLookup) / sizeof(TypeLookup); - - for (int i = 0; i < count; ++i) - if (qt_typeLookup[i].pixelFormat == format) - return qt_typeLookup[i].mediaType; - - return MEDIASUBTYPE_None; -} - -QVideoSurfaceFormat DirectShowMediaType::videoFormatFromType(const AM_MEDIA_TYPE *type) -{ - if (!type) - return QVideoSurfaceFormat(); - - const int count = sizeof(qt_typeLookup) / sizeof(TypeLookup); - - for (int i = 0; i < count; ++i) { - if (IsEqualGUID(qt_typeLookup[i].mediaType, type->subtype) && type->cbFormat > 0) { - if (IsEqualGUID(type->formattype, FORMAT_VideoInfo)) { - VIDEOINFOHEADER *header = reinterpret_cast(type->pbFormat); - - QVideoSurfaceFormat format( - QSize(header->bmiHeader.biWidth, qAbs(header->bmiHeader.biHeight)), - qt_typeLookup[i].pixelFormat); - - if (header->AvgTimePerFrame > 0) - format.setFrameRate(10000 /header->AvgTimePerFrame); - - format.setScanLineDirection(scanLineDirection(format.pixelFormat(), header->bmiHeader)); - - return format; - } else if (IsEqualGUID(type->formattype, FORMAT_VideoInfo2)) { - VIDEOINFOHEADER2 *header = reinterpret_cast(type->pbFormat); - - QVideoSurfaceFormat format( - QSize(header->bmiHeader.biWidth, qAbs(header->bmiHeader.biHeight)), - qt_typeLookup[i].pixelFormat); - - if (header->AvgTimePerFrame > 0) - format.setFrameRate(10000 / header->AvgTimePerFrame); - - format.setScanLineDirection(scanLineDirection(format.pixelFormat(), header->bmiHeader)); - - return format; - } - } - } - return QVideoSurfaceFormat(); -} - -QVideoFrame::PixelFormat DirectShowMediaType::pixelFormatFromType(const AM_MEDIA_TYPE *type) -{ - if (!type) - return QVideoFrame::Format_Invalid; - - const int count = sizeof(qt_typeLookup) / sizeof(TypeLookup); - - for (int i = 0; i < count; ++i) { - if (IsEqualGUID(qt_typeLookup[i].mediaType, type->subtype)) { - return qt_typeLookup[i].pixelFormat; - } - } - - return QVideoFrame::Format_Invalid; -} - -#define PAD_TO_DWORD(x) (((x) + 3) & ~3) -int DirectShowMediaType::bytesPerLine(const QVideoSurfaceFormat &format) -{ - switch (format.pixelFormat()) { - // 32 bpp packed formats. - case QVideoFrame::Format_ARGB32: - case QVideoFrame::Format_RGB32: - case QVideoFrame::Format_AYUV444: - return format.frameWidth() * 4; - // 24 bpp packed formats. - case QVideoFrame::Format_RGB24: - return PAD_TO_DWORD(format.frameWidth() * 3); - // 16 bpp packed formats. - case QVideoFrame::Format_RGB565: - case QVideoFrame::Format_RGB555: - case QVideoFrame::Format_YUYV: - case QVideoFrame::Format_UYVY: - return PAD_TO_DWORD(format.frameWidth() * 2); - // Planar formats. - case QVideoFrame::Format_YV12: - case QVideoFrame::Format_YUV420P: - case QVideoFrame::Format_IMC1: - case QVideoFrame::Format_IMC2: - case QVideoFrame::Format_IMC3: - case QVideoFrame::Format_IMC4: - case QVideoFrame::Format_NV12: - return format.frameWidth(); - default: - return 0; - } -} - -QVideoSurfaceFormat::Direction DirectShowMediaType::scanLineDirection(QVideoFrame::PixelFormat pixelFormat, const BITMAPINFOHEADER &bmiHeader) -{ - /* MSDN http://msdn.microsoft.com/en-us/library/windows/desktop/dd318229(v=vs.85).aspx */ - /* For uncompressed RGB bitmaps: - * if biHeight is positive, the bitmap is a bottom-up DIB with the origin at the lower left corner. - * If biHeight is negative, the bitmap is a top-down DIB with the origin at the upper left corner. - * - * For YUV bitmaps: - * the bitmap is always top-down, regardless of the sign of biHeight. - * Decoders should offer YUV formats with postive biHeight, but for backward compatibility they should accept YUV formats with either positive or negative biHeight. - * - * For compressed formats: - * biHeight must be positive, regardless of image orientation. - */ - switch (pixelFormat) - { - case QVideoFrame::Format_ARGB32: - case QVideoFrame::Format_RGB32: - case QVideoFrame::Format_RGB24: - case QVideoFrame::Format_RGB565: - case QVideoFrame::Format_RGB555: - return bmiHeader.biHeight < 0 - ? QVideoSurfaceFormat::TopToBottom - : QVideoSurfaceFormat::BottomToTop; - default: - return QVideoSurfaceFormat::TopToBottom; - } -} diff --git a/src/plugins/directshow/helpers/directshowmediatype.h b/src/plugins/directshow/helpers/directshowmediatype.h deleted file mode 100644 index 7f495f3b2..000000000 --- a/src/plugins/directshow/helpers/directshowmediatype.h +++ /dev/null @@ -1,97 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWMEDIATYPE_H -#define DIRECTSHOWMEDIATYPE_H - -#include - -#include - -#include -#include - -QT_BEGIN_NAMESPACE - -class DirectShowMediaType -{ -public: - DirectShowMediaType(); - DirectShowMediaType(const DirectShowMediaType &other); - DirectShowMediaType(DirectShowMediaType &&other); - explicit DirectShowMediaType(const AM_MEDIA_TYPE &type); - explicit DirectShowMediaType(AM_MEDIA_TYPE &&type); - ~DirectShowMediaType() { clear(mediaType); } - - DirectShowMediaType &operator =(const DirectShowMediaType &other); - DirectShowMediaType &operator =(DirectShowMediaType &&other); - - void clear() { clear(mediaType); } - - inline AM_MEDIA_TYPE *operator &() Q_DECL_NOTHROW { return &mediaType; } - inline AM_MEDIA_TYPE *operator ->() Q_DECL_NOTHROW { return &mediaType; } - - inline const AM_MEDIA_TYPE *operator &() const Q_DECL_NOTHROW { return &mediaType; } - inline const AM_MEDIA_TYPE *operator ->() const Q_DECL_NOTHROW { return &mediaType; } - - static void init(AM_MEDIA_TYPE *type); - static void copy(AM_MEDIA_TYPE *target, const AM_MEDIA_TYPE *source); - static void copyToUninitialized(AM_MEDIA_TYPE *target, const AM_MEDIA_TYPE *source); - static void move(AM_MEDIA_TYPE *target, AM_MEDIA_TYPE **source); - static void move(AM_MEDIA_TYPE *target, AM_MEDIA_TYPE &source); - static void clear(AM_MEDIA_TYPE &type); - static void deleteType(AM_MEDIA_TYPE *type); - static bool isPartiallySpecified(const AM_MEDIA_TYPE *mediaType); - static bool isCompatible(const AM_MEDIA_TYPE *a, const AM_MEDIA_TYPE *b); - static GUID convertPixelFormat(QVideoFrame::PixelFormat format); - - static QVideoSurfaceFormat videoFormatFromType(const AM_MEDIA_TYPE *type); - static QVideoFrame::PixelFormat pixelFormatFromType(const AM_MEDIA_TYPE *type); - static int bytesPerLine(const QVideoSurfaceFormat &format); - static QVideoSurfaceFormat::Direction scanLineDirection(QVideoFrame::PixelFormat pixelFormat, const BITMAPINFOHEADER &bmiHeader); - -private: - AM_MEDIA_TYPE mediaType; -}; - -Q_DECLARE_TYPEINFO(DirectShowMediaType, Q_MOVABLE_TYPE); - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/directshow/helpers/directshowmediatypeenum.cpp b/src/plugins/directshow/helpers/directshowmediatypeenum.cpp deleted file mode 100644 index 8fbdf7dea..000000000 --- a/src/plugins/directshow/helpers/directshowmediatypeenum.cpp +++ /dev/null @@ -1,117 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowmediatypeenum.h" - -#include "directshowpin.h" - -DirectShowMediaTypeEnum::DirectShowMediaTypeEnum(DirectShowPin *pin) - : m_pin(pin) - , m_mediaTypes(pin->supportedMediaTypes()) - , m_index(0) -{ - m_pin->AddRef(); -} - -DirectShowMediaTypeEnum::DirectShowMediaTypeEnum(const QList &types) - : m_pin(NULL) - , m_mediaTypes(types) - , m_index(0) -{ -} - -DirectShowMediaTypeEnum::~DirectShowMediaTypeEnum() -{ - if (m_pin) - m_pin->Release(); -} - -HRESULT DirectShowMediaTypeEnum::getInterface(REFIID riid, void **ppvObject) -{ - if (riid == IID_IEnumMediaTypes) { - return GetInterface(static_cast(this), ppvObject); - } else { - return DirectShowObject::getInterface(riid, ppvObject); - } -} - -HRESULT DirectShowMediaTypeEnum::Next(ULONG cMediaTypes, AM_MEDIA_TYPE **ppMediaTypes, ULONG *pcFetched) -{ - if (ppMediaTypes && (pcFetched || cMediaTypes == 1)) { - ULONG count = qBound(0, cMediaTypes, m_mediaTypes.count() - m_index); - - for (ULONG i = 0; i < count; ++i, ++m_index) { - ppMediaTypes[i] = reinterpret_cast(CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE))); - DirectShowMediaType::copyToUninitialized(ppMediaTypes[i], &m_mediaTypes.at(m_index)); - } - - if (pcFetched) - *pcFetched = count; - - return count == cMediaTypes ? S_OK : S_FALSE; - } else { - return E_POINTER; - } -} - -HRESULT DirectShowMediaTypeEnum::Skip(ULONG cMediaTypes) -{ - m_index = qMin(int(m_index + cMediaTypes), m_mediaTypes.count()); - return m_index < m_mediaTypes.count() ? S_OK : S_FALSE; -} - -HRESULT DirectShowMediaTypeEnum::Reset() -{ - m_index = 0; - return S_OK; -} - -HRESULT DirectShowMediaTypeEnum::Clone(IEnumMediaTypes **ppEnum) -{ - if (ppEnum) { - if (m_pin) - *ppEnum = new DirectShowMediaTypeEnum(m_pin); - else - *ppEnum = new DirectShowMediaTypeEnum(m_mediaTypes); - return S_OK; - } else { - return E_POINTER; - } -} - diff --git a/src/plugins/directshow/helpers/directshowmediatypeenum.h b/src/plugins/directshow/helpers/directshowmediatypeenum.h deleted file mode 100644 index 9b058fc5b..000000000 --- a/src/plugins/directshow/helpers/directshowmediatypeenum.h +++ /dev/null @@ -1,80 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWMEDIATYPEENUM_H -#define DIRECTSHOWMEDIATYPEENUM_H - -#include "directshowobject.h" -#include - -QT_BEGIN_NAMESPACE - -class DirectShowPin; -class DirectShowMediaType; - -class DirectShowMediaTypeEnum : public DirectShowObject - , public IEnumMediaTypes -{ - DIRECTSHOW_OBJECT - -public: - DirectShowMediaTypeEnum(DirectShowPin *pin); - DirectShowMediaTypeEnum(const QList &types); - ~DirectShowMediaTypeEnum(); - - // DirectShowObject - HRESULT getInterface(REFIID riid, void **ppvObject); - - // IEnumMediaTypes - STDMETHODIMP Next(ULONG cMediaTypes, AM_MEDIA_TYPE **ppMediaTypes, ULONG *pcFetched); - STDMETHODIMP Skip(ULONG cMediaTypes); - STDMETHODIMP Reset(); - STDMETHODIMP Clone(IEnumMediaTypes **ppEnum); - -private: - Q_DISABLE_COPY(DirectShowMediaTypeEnum) - - DirectShowPin *m_pin; - QList m_mediaTypes; - int m_index; -}; - -QT_END_NAMESPACE - -#endif // DIRECTSHOWMEDIATYPEENUM_H diff --git a/src/plugins/directshow/helpers/directshowobject.cpp b/src/plugins/directshow/helpers/directshowobject.cpp deleted file mode 100644 index db1817a8d..000000000 --- a/src/plugins/directshow/helpers/directshowobject.cpp +++ /dev/null @@ -1,86 +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 "directshowobject.h" - -QT_BEGIN_NAMESPACE - -DirectShowObject::DirectShowObject() - : m_ref(1) -{ -} - -DirectShowObject::~DirectShowObject() -{ - Q_ASSERT(m_ref == 0); -} - -HRESULT DirectShowObject::getInterface(const IID &riid, void **ppvObject) -{ - Q_UNUSED(riid) - *ppvObject = NULL; - return E_NOINTERFACE; -} - -ULONG DirectShowObject::ref() -{ - return InterlockedIncrement(&m_ref); -} - -ULONG DirectShowObject::unref() -{ - ULONG ref = InterlockedDecrement(&m_ref); - if (ref == 0) - delete this; - - return ref; -} - -HRESULT GetInterface(IUnknown *pUnk, void **ppv) -{ - if (!ppv) - return E_POINTER; - - *ppv = pUnk; - pUnk->AddRef(); - - return S_OK; -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/helpers/directshowobject.h b/src/plugins/directshow/helpers/directshowobject.h deleted file mode 100644 index cfac16f61..000000000 --- a/src/plugins/directshow/helpers/directshowobject.h +++ /dev/null @@ -1,82 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWOBJECT_H -#define DIRECTSHOWOBJECT_H - -#include "directshowglobal.h" - -QT_BEGIN_NAMESPACE - -class DirectShowObject -{ -public: - DirectShowObject(); - virtual ~DirectShowObject(); - - virtual HRESULT getInterface(REFIID riid, void **ppvObject); - ULONG ref(); - ULONG unref(); - -private: - Q_DISABLE_COPY(DirectShowObject) - - volatile LONG m_ref; -}; - -HRESULT GetInterface(IUnknown *pUnk, void **ppv); - -#define DIRECTSHOW_OBJECT \ -public: \ - STDMETHODIMP QueryInterface(REFIID riid, void **ppv) { \ - if (riid == IID_IUnknown) \ - return GetInterface(reinterpret_cast(this), ppv); \ - else \ - return getInterface(riid, ppv); \ - }; \ - STDMETHODIMP_(ULONG) AddRef() { \ - return ref(); \ - }; \ - STDMETHODIMP_(ULONG) Release() { \ - return unref(); \ - }; - -QT_END_NAMESPACE - -#endif // DIRECTSHOWOBJECT_H diff --git a/src/plugins/directshow/helpers/directshowpin.cpp b/src/plugins/directshow/helpers/directshowpin.cpp deleted file mode 100644 index b49c3f8a4..000000000 --- a/src/plugins/directshow/helpers/directshowpin.cpp +++ /dev/null @@ -1,740 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowpin.h" - -#include "directshowmediatype.h" -#include "directshowbasefilter.h" -#include "directshowmediatypeenum.h" - -#include - -QT_BEGIN_NAMESPACE - -DirectShowPin::DirectShowPin(DirectShowBaseFilter *filter, const QString &name, PIN_DIRECTION direction) - : m_mutex(QMutex::Recursive) - , m_filter(filter) - , m_name(name) - , m_direction(direction) - , m_peerPin(NULL) -{ -} - -DirectShowPin::~DirectShowPin() -{ - -} - -HRESULT DirectShowPin::getInterface(const IID &riid, void **ppvObject) -{ - if (riid == IID_IPin) - return GetInterface(static_cast(this), ppvObject); - else - return DirectShowObject::getInterface(riid, ppvObject); -} - - - -HRESULT DirectShowPin::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) -{ - if (!pReceivePin) - return E_POINTER; - - HRESULT hr = E_FAIL; - QMutexLocker locker(&m_mutex); - - if (m_peerPin) - return VFW_E_ALREADY_CONNECTED; - if (m_filter->state() != State_Stopped) - return VFW_E_NOT_STOPPED; - - PIN_DIRECTION pd; - pReceivePin->QueryDirection(&pd); - if (pd == m_direction) - return VFW_E_INVALID_DIRECTION; - - if (pmt != NULL && DirectShowMediaType::isPartiallySpecified(pmt)) { - // If the type is fully specified, use it - hr = tryConnect(pReceivePin, pmt); - } else { - IEnumMediaTypes *enumMediaTypes = NULL; - - // First, try the receiving pin's preferred types - if (SUCCEEDED(pReceivePin->EnumMediaTypes(&enumMediaTypes))) { - hr = tryMediaTypes(pReceivePin, pmt, enumMediaTypes); - enumMediaTypes->Release(); - } - // Then, try this pin's preferred types - if (FAILED(hr) && SUCCEEDED(EnumMediaTypes(&enumMediaTypes))) { - hr = tryMediaTypes(pReceivePin, pmt, enumMediaTypes); - enumMediaTypes->Release(); - } - } - - if (FAILED(hr)) { - return ((hr != E_FAIL) && (hr != E_INVALIDARG) && (hr != VFW_E_TYPE_NOT_ACCEPTED)) - ? hr : VFW_E_NO_ACCEPTABLE_TYPES; - } - - return S_OK; -} - -HRESULT DirectShowPin::tryMediaTypes(IPin *pin, const AM_MEDIA_TYPE *partialType, IEnumMediaTypes *enumMediaTypes) -{ - HRESULT hr = enumMediaTypes->Reset(); - if (FAILED(hr)) - return hr; - - AM_MEDIA_TYPE *mediaType = NULL; - ULONG mediaCount = 0; - HRESULT hrFailure = VFW_E_NO_ACCEPTABLE_TYPES; - - for (; enumMediaTypes->Next(1, &mediaType, &mediaCount) == S_OK;) { - - if (mediaType && (partialType == NULL || DirectShowMediaType::isCompatible(mediaType, partialType))) { - hr = tryConnect(pin, mediaType); - - if (FAILED(hr) && (hr != E_FAIL) - && (hr != E_INVALIDARG) - && (hr != VFW_E_TYPE_NOT_ACCEPTED)) { - hrFailure = hr; - } - } - - if (mediaType) - DirectShowMediaType::deleteType(mediaType); - - if (SUCCEEDED(hr)) - return S_OK; - } - - return hrFailure; -} - -HRESULT DirectShowPin::tryConnect(IPin *pin, const AM_MEDIA_TYPE *type) -{ - if (!isMediaTypeSupported(type)) - return VFW_E_TYPE_NOT_ACCEPTED; - - m_peerPin = pin; - m_peerPin->AddRef(); - - HRESULT hr; - if (!setMediaType(type)) { - hr = VFW_E_TYPE_NOT_ACCEPTED; - } else { - hr = pin->ReceiveConnection(this, type); - if (SUCCEEDED(hr)) { - hr = completeConnection(pin); - if (FAILED(hr)) - pin->Disconnect(); - } - } - - if (FAILED(hr)) { - connectionEnded(); - m_peerPin->Release(); - m_peerPin = NULL; - setMediaType(NULL); - return hr; - } - - return S_OK; -} - -HRESULT DirectShowPin::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt) -{ - if (!pConnector || !pmt) - return E_POINTER; - - QMutexLocker locker(&m_mutex); - - if (m_peerPin) - return VFW_E_ALREADY_CONNECTED; - if (m_filter->state() != State_Stopped) - return VFW_E_NOT_STOPPED; - - PIN_DIRECTION pd; - pConnector->QueryDirection(&pd); - if (pd == m_direction) - return VFW_E_INVALID_DIRECTION; - - if (!isMediaTypeSupported(pmt)) - return VFW_E_TYPE_NOT_ACCEPTED; - - m_peerPin = pConnector; - m_peerPin->AddRef(); - - HRESULT hr; - if (!setMediaType(pmt)) - hr = VFW_E_TYPE_NOT_ACCEPTED; - else - hr = completeConnection(pConnector); - - if (FAILED(hr)) { - connectionEnded(); - m_peerPin->Release(); - m_peerPin = NULL; - setMediaType(NULL); - return hr; - } - - return S_OK; -} - -HRESULT DirectShowPin::Disconnect() -{ - QMutexLocker locker(&m_mutex); - - if (m_filter->state() != State_Stopped) - return VFW_E_NOT_STOPPED; - - if (m_peerPin) { - HRESULT hr = connectionEnded(); - if (FAILED(hr)) - return hr; - - m_peerPin->Release(); - m_peerPin = NULL; - - setMediaType(NULL); - - return S_OK; - } - - return S_FALSE; -} - -HRESULT DirectShowPin::ConnectedTo(IPin **ppPin) -{ - if (!ppPin) { - return E_POINTER; - } else { - QMutexLocker locker(&m_mutex); - - if (!m_peerPin) { - *ppPin = 0; - return VFW_E_NOT_CONNECTED; - } else { - m_peerPin->AddRef(); - *ppPin = m_peerPin; - return S_OK; - } - } -} - -HRESULT DirectShowPin::ConnectionMediaType(AM_MEDIA_TYPE *pmt) -{ - if (!pmt) { - return E_POINTER; - } else { - QMutexLocker locker(&m_mutex); - - if (!m_peerPin) { - DirectShowMediaType::init(pmt); - return VFW_E_NOT_CONNECTED; - } else { - DirectShowMediaType::copy(pmt, &m_mediaType); - return S_OK; - } - } -} - -HRESULT DirectShowPin::QueryPinInfo(PIN_INFO *pInfo) -{ - if (!pInfo) { - return E_POINTER; - } else { - pInfo->pFilter = m_filter; - if (m_filter) { - m_filter->AddRef(); - } - pInfo->dir = m_direction; - - QString name = m_name; - if (name.length() >= MAX_PIN_NAME) - name.truncate(MAX_PIN_NAME - 1); - int length = name.toWCharArray(pInfo->achName); - pInfo->achName[length] = '\0'; - - return S_OK; - } -} - -HRESULT DirectShowPin::QueryId(LPWSTR *Id) -{ - if (!Id) { - return E_POINTER; - } else { - const int bytes = (m_name.length() + 1) * 2; - *Id = static_cast(::CoTaskMemAlloc(bytes)); - ::memcpy(*Id, m_name.utf16(), bytes); - return S_OK; - } -} - -HRESULT DirectShowPin::QueryAccept(const AM_MEDIA_TYPE *pmt) -{ - if (!pmt) - return E_POINTER; - - if (!isMediaTypeSupported(pmt)) - return S_FALSE; - - return S_OK; -} - -HRESULT DirectShowPin::EnumMediaTypes(IEnumMediaTypes **ppEnum) -{ - if (!ppEnum) { - return E_POINTER; - } else { - *ppEnum = new DirectShowMediaTypeEnum(this); - return S_OK; - } -} - -HRESULT DirectShowPin::QueryInternalConnections(IPin **apPin, ULONG *nPin) -{ - Q_UNUSED(apPin); - Q_UNUSED(nPin); - return E_NOTIMPL; -} - -HRESULT DirectShowPin::EndOfStream() -{ - return S_OK; -} - -HRESULT DirectShowPin::BeginFlush() -{ - return E_UNEXPECTED; -} - -HRESULT DirectShowPin::EndFlush() -{ - return E_UNEXPECTED; -} - -HRESULT DirectShowPin::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) -{ - Q_UNUSED(tStart); - Q_UNUSED(tStop); - Q_UNUSED(dRate); - return S_OK; -} - -HRESULT DirectShowPin::QueryDirection(PIN_DIRECTION *pPinDir) -{ - if (!pPinDir) { - return E_POINTER; - } else { - *pPinDir = m_direction; - return S_OK; - } -} - -QList DirectShowPin::supportedMediaTypes() -{ - return QList(); -} - -bool DirectShowPin::setMediaType(const AM_MEDIA_TYPE *type) -{ - if (!type) - m_mediaType.clear(); - else - DirectShowMediaType::copy(&m_mediaType, type); - - return true; -} - -HRESULT DirectShowPin::completeConnection(IPin *pin) -{ - Q_UNUSED(pin) - return S_OK; -} - -HRESULT DirectShowPin::connectionEnded() -{ - return S_OK; -} - -HRESULT DirectShowPin::setActive(bool active) -{ - Q_UNUSED(active) - return S_OK; -} - - -/* DirectShowOutputPin */ - -DirectShowOutputPin::DirectShowOutputPin(DirectShowBaseFilter *filter, const QString &name) - : DirectShowPin(filter, name, PINDIR_OUTPUT) - , m_allocator(NULL) - , m_inputPin(NULL) -{ - -} - -DirectShowOutputPin::~DirectShowOutputPin() -{ -} - -HRESULT DirectShowOutputPin::completeConnection(IPin *pin) -{ - if (!pin) - return E_POINTER; - - Q_ASSERT(m_inputPin == NULL); - Q_ASSERT(m_allocator == NULL); - - HRESULT hr = pin->QueryInterface(IID_PPV_ARGS(&m_inputPin)); - if (FAILED(hr)) - return hr; - - ALLOCATOR_PROPERTIES prop; - ZeroMemory(&prop, sizeof(prop)); - m_inputPin->GetAllocatorRequirements(&prop); - if (prop.cBuffers <= 0) - prop.cBuffers = 1; - if (prop.cbBuffer <= 0) - prop.cbBuffer = 1; - if (prop.cbAlign <= 0) - prop.cbAlign = 1; - - // Use the connected input pin's allocator if it has one - hr = m_inputPin->GetAllocator(&m_allocator); - if (SUCCEEDED(hr)) { - ALLOCATOR_PROPERTIES actualProperties; - hr = m_allocator->SetProperties(&prop, &actualProperties); - - if (SUCCEEDED(hr)) { - hr = m_inputPin->NotifyAllocator(m_allocator, FALSE); - if (SUCCEEDED(hr)) - return S_OK; - } - - m_allocator->Release(); - m_allocator = NULL; - } - - // Otherwise, allocate its own allocator - m_allocator = com_new(CLSID_MemoryAllocator); - if (!m_allocator) { - hr = E_OUTOFMEMORY; - } else { - ALLOCATOR_PROPERTIES actualProperties; - hr = m_allocator->SetProperties(&prop, &actualProperties); - - if (SUCCEEDED(hr)) { - hr = m_inputPin->NotifyAllocator(m_allocator, FALSE); - if (SUCCEEDED(hr)) - return S_OK; - } - - m_allocator->Release(); - m_allocator = NULL; - } - - return hr; -} - -HRESULT DirectShowOutputPin::connectionEnded() -{ - if (m_allocator) { - HRESULT hr = m_allocator->Decommit(); - if (FAILED(hr)) - return hr; - - m_allocator->Release(); - m_allocator = NULL; - } - - if (m_inputPin) { - m_inputPin->Release(); - m_inputPin = NULL; - } - - return S_OK; -} - -HRESULT DirectShowOutputPin::setActive(bool active) -{ - if (!m_allocator) - return VFW_E_NO_ALLOCATOR; - - return active ? m_allocator->Commit() - : m_allocator->Decommit(); -} - -HRESULT DirectShowOutputPin::EndOfStream() -{ - return E_UNEXPECTED; -} - - -/* DirectShowInputPin */ - -DirectShowInputPin::DirectShowInputPin(DirectShowBaseFilter *filter, const QString &name) - : DirectShowPin(filter, name, PINDIR_INPUT) - , m_allocator(NULL) - , m_flushing(false) - , m_inErrorState(false) -{ - ZeroMemory(&m_sampleProperties, sizeof(m_sampleProperties)); -} - -DirectShowInputPin::~DirectShowInputPin() -{ - -} - -HRESULT DirectShowInputPin::getInterface(const IID &riid, void **ppvObject) -{ - if (riid == IID_IMemInputPin) - return GetInterface(static_cast(this), ppvObject); - else - return DirectShowPin::getInterface(riid, ppvObject); -} - -HRESULT DirectShowInputPin::connectionEnded() -{ - if (m_allocator) { - HRESULT hr = m_allocator->Decommit(); - if (FAILED(hr)) - return hr; - - m_allocator->Release(); - m_allocator = NULL; - } - - return S_OK; -} - -HRESULT DirectShowInputPin::setActive(bool active) -{ - if (!active) { - m_inErrorState = false; - - if (!m_allocator) - return VFW_E_NO_ALLOCATOR; - - m_flushing = false; - return m_allocator->Decommit(); - } - - return S_OK; -} - -HRESULT DirectShowInputPin::EndOfStream() -{ - if (m_filter->state() == State_Stopped) - return VFW_E_WRONG_STATE; - if (m_flushing) - return S_FALSE; - if (m_inErrorState) - return VFW_E_RUNTIME_ERROR; - - return S_OK; -} - -HRESULT DirectShowInputPin::BeginFlush() -{ - QMutexLocker locker(&m_mutex); - m_flushing = true; - return S_OK; -} - -HRESULT DirectShowInputPin::EndFlush() -{ - QMutexLocker locker(&m_mutex); - m_flushing = false; - m_inErrorState = false; - return S_OK; -} - -HRESULT DirectShowInputPin::GetAllocator(IMemAllocator **ppAllocator) -{ - if (!ppAllocator) - return E_POINTER; - - QMutexLocker locker(&m_mutex); - - if (!m_allocator) { - m_allocator = com_new(CLSID_MemoryAllocator);; - if (!m_allocator) - return E_OUTOFMEMORY; - } - - *ppAllocator = m_allocator; - m_allocator->AddRef(); - - return S_OK; -} - -HRESULT DirectShowInputPin::NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly) -{ - Q_UNUSED(bReadOnly) - - if (!pAllocator) - return E_POINTER; - - QMutexLocker locker(&m_mutex); - - if (m_allocator) - m_allocator->Release(); - - m_allocator = pAllocator; - m_allocator->AddRef(); - - return S_OK; -} - -HRESULT DirectShowInputPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps) -{ - Q_UNUSED(pProps) - return E_NOTIMPL; -} - -HRESULT DirectShowInputPin::Receive(IMediaSample *pSample) -{ - if (!pSample) - return E_POINTER; - if (m_filter->state() == State_Stopped) - return VFW_E_WRONG_STATE; - if (m_flushing) - return S_FALSE; - if (m_inErrorState) - return VFW_E_RUNTIME_ERROR; - - HRESULT hr = S_OK; - - IMediaSample2 *sample2; - if (SUCCEEDED(pSample->QueryInterface(IID_PPV_ARGS(&sample2)))) { - hr = sample2->GetProperties(sizeof(m_sampleProperties), (PBYTE)&m_sampleProperties); - sample2->Release(); - if (FAILED(hr)) - return hr; - } else { - m_sampleProperties.cbData = sizeof(m_sampleProperties); - m_sampleProperties.dwTypeSpecificFlags = 0; - m_sampleProperties.dwStreamId = AM_STREAM_MEDIA; - m_sampleProperties.dwSampleFlags = 0; - if (pSample->IsDiscontinuity() == S_OK) - m_sampleProperties.dwSampleFlags |= AM_SAMPLE_DATADISCONTINUITY; - if (pSample->IsPreroll() == S_OK) - m_sampleProperties.dwSampleFlags |= AM_SAMPLE_PREROLL; - if (pSample->IsSyncPoint() == S_OK) - m_sampleProperties.dwSampleFlags |= AM_SAMPLE_SPLICEPOINT; - if (SUCCEEDED(pSample->GetTime(&m_sampleProperties.tStart, - &m_sampleProperties.tStop))) { - m_sampleProperties.dwSampleFlags |= AM_SAMPLE_TIMEVALID | AM_SAMPLE_STOPVALID; - } - if (pSample->GetMediaType(&m_sampleProperties.pMediaType) == S_OK) - m_sampleProperties.dwSampleFlags |= AM_SAMPLE_TYPECHANGED; - pSample->GetPointer(&m_sampleProperties.pbBuffer); - m_sampleProperties.lActual = pSample->GetActualDataLength(); - m_sampleProperties.cbBuffer = pSample->GetSize(); - } - - - if (!(m_sampleProperties.dwSampleFlags & AM_SAMPLE_TYPECHANGED)) - return S_OK; - - if (isMediaTypeSupported(m_sampleProperties.pMediaType)) - return S_OK; - - m_inErrorState = true; - EndOfStream(); - m_filter->NotifyEvent(EC_ERRORABORT, VFW_E_TYPE_NOT_ACCEPTED, 0); - return VFW_E_INVALIDMEDIATYPE; -} - -HRESULT DirectShowInputPin::ReceiveMultiple(IMediaSample **pSamples, long nSamples, long *nSamplesProcessed) -{ - if (!pSamples || !nSamplesProcessed) - return E_POINTER; - - HRESULT hr = S_OK; - *nSamplesProcessed = 0; - while (nSamples-- > 0) { - hr = Receive(pSamples[*nSamplesProcessed]); - if (hr != S_OK) - break; - (*nSamplesProcessed)++; - } - return hr; -} - -HRESULT DirectShowInputPin::ReceiveCanBlock() -{ - int outputPins = 0; - - const QList pinList = m_filter->pins(); - for (DirectShowPin *pin : pinList) { - PIN_DIRECTION pd; - HRESULT hr = pin->QueryDirection(&pd); - if (FAILED(hr)) - return hr; - - if (pd == PINDIR_OUTPUT) { - IPin *connected; - hr = pin->ConnectedTo(&connected); - if (SUCCEEDED(hr)) { - ++outputPins; - IMemInputPin *inputPin; - hr = connected->QueryInterface(IID_PPV_ARGS(&inputPin)); - connected->Release(); - if (SUCCEEDED(hr)) { - hr = inputPin->ReceiveCanBlock(); - inputPin->Release(); - if (hr != S_FALSE) - return S_OK; - } else { - return S_OK; - } - } - } - } - - return outputPins == 0 ? S_OK : S_FALSE; -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/helpers/directshowpin.h b/src/plugins/directshow/helpers/directshowpin.h deleted file mode 100644 index 97e808384..000000000 --- a/src/plugins/directshow/helpers/directshowpin.h +++ /dev/null @@ -1,192 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2017 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWPIN_H -#define DIRECTSHOWPIN_H - -#include "directshowobject.h" - -#include "directshowmediatype.h" -#include -#include - -QT_BEGIN_NAMESPACE - -class DirectShowBaseFilter; - -class DirectShowPin : public DirectShowObject - , public IPin -{ - DIRECTSHOW_OBJECT - -public: - virtual ~DirectShowPin(); - - QString name() const { return m_name; } - bool isConnected() const { return m_peerPin != NULL; } - - virtual bool isMediaTypeSupported(const AM_MEDIA_TYPE *type) = 0; - virtual QList supportedMediaTypes(); - virtual bool setMediaType(const AM_MEDIA_TYPE *type); - - virtual HRESULT completeConnection(IPin *pin); - virtual HRESULT connectionEnded(); - - virtual HRESULT setActive(bool active); - - // DirectShowObject - HRESULT getInterface(REFIID riid, void **ppvObject); - - // IPin - STDMETHODIMP Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt); - STDMETHODIMP ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt); - STDMETHODIMP Disconnect(); - STDMETHODIMP ConnectedTo(IPin **ppPin); - - STDMETHODIMP ConnectionMediaType(AM_MEDIA_TYPE *pmt); - - STDMETHODIMP QueryPinInfo(PIN_INFO *pInfo); - STDMETHODIMP QueryId(LPWSTR *Id); - - STDMETHODIMP QueryAccept(const AM_MEDIA_TYPE *pmt); - - STDMETHODIMP EnumMediaTypes(IEnumMediaTypes **ppEnum); - - STDMETHODIMP QueryInternalConnections(IPin **apPin, ULONG *nPin); - - STDMETHODIMP EndOfStream(); - - STDMETHODIMP BeginFlush(); - STDMETHODIMP EndFlush(); - - STDMETHODIMP NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate); - - STDMETHODIMP QueryDirection(PIN_DIRECTION *pPinDir); - -protected: - DirectShowPin(DirectShowBaseFilter *filter, const QString &name, PIN_DIRECTION direction); - - QMutex m_mutex; - - DirectShowBaseFilter *m_filter; - QString m_name; - PIN_DIRECTION m_direction; - - IPin *m_peerPin; - DirectShowMediaType m_mediaType; - -private: - Q_DISABLE_COPY(DirectShowPin) - HRESULT tryMediaTypes(IPin *pin, const AM_MEDIA_TYPE *type, IEnumMediaTypes *enumMediaTypes); - HRESULT tryConnect(IPin *pin, const AM_MEDIA_TYPE *type); -}; - - -class DirectShowOutputPin : public DirectShowPin -{ - DIRECTSHOW_OBJECT - -public: - virtual ~DirectShowOutputPin(); - - // DirectShowPin - virtual HRESULT completeConnection(IPin *pin); - virtual HRESULT connectionEnded(); - virtual HRESULT setActive(bool active); - - // IPin - STDMETHODIMP EndOfStream(); - -protected: - DirectShowOutputPin(DirectShowBaseFilter *filter, const QString &name); - - IMemAllocator *m_allocator; - IMemInputPin *m_inputPin; - -private: - Q_DISABLE_COPY(DirectShowOutputPin) -}; - - -class DirectShowInputPin : public DirectShowPin - , public IMemInputPin -{ - DIRECTSHOW_OBJECT - -public: - virtual ~DirectShowInputPin(); - - const AM_SAMPLE2_PROPERTIES *currentSampleProperties() const { return &m_sampleProperties; } - - // DirectShowObject - HRESULT getInterface(REFIID riid, void **ppvObject); - - // DirectShowPin - HRESULT connectionEnded(); - HRESULT setActive(bool active); - - // IPin - STDMETHODIMP EndOfStream(); - STDMETHODIMP BeginFlush(); - STDMETHODIMP EndFlush(); - - // IMemInputPin - STDMETHODIMP GetAllocator(IMemAllocator **ppAllocator); - STDMETHODIMP NotifyAllocator(IMemAllocator *pAllocator, BOOL bReadOnly); - STDMETHODIMP GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps); - - STDMETHODIMP Receive(IMediaSample *pSample); - STDMETHODIMP ReceiveMultiple(IMediaSample **pSamples, long nSamples, long *nSamplesProcessed); - STDMETHODIMP ReceiveCanBlock(); - -protected: - DirectShowInputPin(DirectShowBaseFilter *filter, const QString &name); - - IMemAllocator *m_allocator; - bool m_flushing; - bool m_inErrorState; - AM_SAMPLE2_PROPERTIES m_sampleProperties; - -private: - Q_DISABLE_COPY(DirectShowInputPin) -}; - -QT_END_NAMESPACE - -#endif // DIRECTSHOWPIN_H diff --git a/src/plugins/directshow/helpers/directshowpinenum.cpp b/src/plugins/directshow/helpers/directshowpinenum.cpp deleted file mode 100644 index 910bba77d..000000000 --- a/src/plugins/directshow/helpers/directshowpinenum.cpp +++ /dev/null @@ -1,130 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowpinenum.h" -#include "directshowbasefilter.h" - -QT_BEGIN_NAMESPACE - -DirectShowPinEnum::DirectShowPinEnum(DirectShowBaseFilter *filter) - : m_filter(filter) - , m_index(0) -{ - m_filter->AddRef(); - const QList pinList = filter->pins(); - for (DirectShowPin *pin : pinList) { - pin->AddRef(); - m_pins.append(pin); - } -} - -DirectShowPinEnum::DirectShowPinEnum(const QList &pins) - : m_filter(NULL) - , m_pins(pins) - , m_index(0) -{ - for (IPin *pin : qAsConst(m_pins)) - pin->AddRef(); -} - -DirectShowPinEnum::~DirectShowPinEnum() -{ - for (IPin *pin : qAsConst(m_pins)) - pin->Release(); - if (m_filter) - m_filter->Release(); -} - -HRESULT DirectShowPinEnum::getInterface(REFIID riid, void **ppvObject) -{ - if (riid == IID_IEnumPins) { - return GetInterface(static_cast(this), ppvObject); - } else { - return DirectShowObject::getInterface(riid, ppvObject); - } -} - -HRESULT DirectShowPinEnum::Next(ULONG cPins, IPin **ppPins, ULONG *pcFetched) -{ - if (ppPins && (pcFetched || cPins == 1)) { - ULONG count = qBound(0, cPins, m_pins.count() - m_index); - - for (ULONG i = 0; i < count; ++i, ++m_index) { - ppPins[i] = m_pins.at(m_index); - ppPins[i]->AddRef(); - } - - if (pcFetched) - *pcFetched = count; - - return count == cPins ? S_OK : S_FALSE; - } else { - return E_POINTER; - } -} - -HRESULT DirectShowPinEnum::Skip(ULONG cPins) -{ - m_index = qMin(int(m_index + cPins), m_pins.count()); - - return m_index < m_pins.count() ? S_OK : S_FALSE; -} - -HRESULT DirectShowPinEnum::Reset() -{ - m_index = 0; - - return S_OK; -} - -HRESULT DirectShowPinEnum::Clone(IEnumPins **ppEnum) -{ - if (ppEnum) { - if (m_filter) - *ppEnum = new DirectShowPinEnum(m_filter); - else - *ppEnum = new DirectShowPinEnum(m_pins); - - return S_OK; - } else { - return E_POINTER; - } -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/helpers/directshowpinenum.h b/src/plugins/directshow/helpers/directshowpinenum.h deleted file mode 100644 index 77214e376..000000000 --- a/src/plugins/directshow/helpers/directshowpinenum.h +++ /dev/null @@ -1,81 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWPINENUM_H -#define DIRECTSHOWPINENUM_H - -#include - -#include -#include "directshowpin.h" - -QT_BEGIN_NAMESPACE - -class DirectShowBaseFilter; - -class DirectShowPinEnum : public DirectShowObject - , public IEnumPins -{ - DIRECTSHOW_OBJECT - -public: - DirectShowPinEnum(DirectShowBaseFilter *filter); - DirectShowPinEnum(const QList &pins); - ~DirectShowPinEnum(); - - // DirectShowObject - HRESULT getInterface(REFIID riid, void **ppvObject); - - // IEnumPins - STDMETHODIMP Next(ULONG cPins, IPin **ppPins, ULONG *pcFetched); - STDMETHODIMP Skip(ULONG cPins); - STDMETHODIMP Reset(); - STDMETHODIMP Clone(IEnumPins **ppEnum); - -private: - Q_DISABLE_COPY(DirectShowPinEnum) - - DirectShowBaseFilter *m_filter; - QList m_pins; - int m_index; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/directshow/helpers/directshowutils.cpp b/src/plugins/directshow/helpers/directshowutils.cpp deleted file mode 100644 index 96fabd6da..000000000 --- a/src/plugins/directshow/helpers/directshowutils.cpp +++ /dev/null @@ -1,313 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowutils.h" - -QT_BEGIN_NAMESPACE - -/** - * @brief DirectShowUtils::isPinConnected - * @param pin - * @param hrOut - * @return - */ -bool DirectShowUtils::isPinConnected(IPin *pin, HRESULT *hrOut) -{ - IPin *connectedPin = nullptr; - const ScopedSafeRelease releasePin { &connectedPin }; - HRESULT hr = S_OK; - if (!hrOut) - hrOut = &hr; - - *hrOut = pin->ConnectedTo(&connectedPin); - if (*hrOut == VFW_E_NOT_CONNECTED) // Not an error in this case - *hrOut = S_OK; - - if (FAILED(*hrOut)) { - qCDebug(qtDirectShowPlugin, "Querying pin connection failed!"); - return false; - } - - return true; -} - -/** - * @brief DirectShowUtils::hasPinDirection - * @param pin - * @param direction - * @param hrOut - * @return - */ -bool DirectShowUtils::hasPinDirection(IPin *pin, PIN_DIRECTION direction, HRESULT *hrOut) -{ - PIN_DIRECTION pinDir; - HRESULT hr = S_OK; - if (!hrOut) - hrOut = &hr; - - *hrOut = pin->QueryDirection(&pinDir); - - if (FAILED(*hrOut)) { - qCDebug(qtDirectShowPlugin, "Querying pin direction failed!"); - return false; - } - - return (pinDir == direction); -} - -/** - * @brief DirectShowUtils::getPin - * @param filter - * @param pinDirection - * @param pin - * @param hrOut - * @return - */ -bool DirectShowUtils::getPin(IBaseFilter *filter, PIN_DIRECTION pinDirection, IPin **pin, HRESULT *hrOut) -{ - IEnumPins *enumPins = nullptr; - const ScopedSafeRelease releaseEnumPins { &enumPins }; - HRESULT hr S_OK; - if (!hrOut) - hrOut = &hr; - - *hrOut = filter->EnumPins(&enumPins); - if (FAILED(*hrOut)) { - qCDebug(qtDirectShowPlugin, "Unable to retrieve pins from the filter!"); - return false; - } - - enumPins->Reset(); - IPin *nextPin = nullptr; - while (enumPins->Next(1, &nextPin, NULL) == S_OK) { - const ScopedSafeRelease releasePin { &nextPin }; - PIN_DIRECTION currentPinDir; - *hrOut = nextPin->QueryDirection(¤tPinDir); - if (currentPinDir == pinDirection) { - *pin = nextPin; - (*pin)->AddRef(); - return true; - } - } - - return false; -} - -/** - * @brief DirectShowUtils::matchPin - * @param pin - * @param pinDirection - * @param shouldBeConnected - * @param hrOut - * @return - */ -bool DirectShowUtils::matchPin(IPin *pin, PIN_DIRECTION pinDirection, BOOL shouldBeConnected, HRESULT *hrOut) -{ - HRESULT hr = S_OK; - if (!hrOut) - hrOut = &hr; - - const BOOL isConnected = isPinConnected(pin, hrOut); - if (FAILED(*hrOut)) // Error reason will already be logged, so just return. - return false; - - if (isConnected == shouldBeConnected) - return hasPinDirection(pin, pinDirection, hrOut); - - return SUCCEEDED(*hrOut); -} - -/** - * @brief DirectShowUtils::findUnconnectedPin - * @param filter - * @param pinDirection - * @param pin - * @param hrOut - * @return - */ -bool DirectShowUtils::findUnconnectedPin(IBaseFilter *filter, PIN_DIRECTION pinDirection, IPin **pin, HRESULT *hrOut) -{ - HRESULT hr = S_OK; - if (!hrOut) - hrOut = &hr; - - IEnumPins *enumPins = nullptr; - const ScopedSafeRelease releaseEnumPins { &enumPins }; - *hrOut = filter->EnumPins(&enumPins); - if (FAILED(*hrOut)) { - qCDebug(qtDirectShowPlugin, "Unable to retrieve pins from the DS filter"); - return false; - } - - IPin *nextPin = nullptr; - while (S_OK == enumPins->Next(1, &nextPin, nullptr)) { - const ScopedSafeRelease releaseNextPin { &nextPin }; - if (matchPin(nextPin, pinDirection, FALSE, hrOut)) { - *pin = nextPin; - (*pin)->AddRef(); - return true; - } - - if (FAILED(*hrOut)) - return false; - } - - qCDebug(qtDirectShowPlugin, "No unconnected pins found"); - *hrOut = VFW_E_NOT_FOUND; - - return false; -} - -/** - * @brief DirectShowUtils::connectFilters - Attempts to connect \a outputPin to \a filter - * @param graph - * @param outputPin - * @param filter - * @param hrOut - * @return - */ -bool DirectShowUtils::connectFilters(IGraphBuilder *graph, IPin *outputPin, IBaseFilter *filter, HRESULT *hrOut) -{ - - // Find an input pin on the downstream filter. - HRESULT hr = S_OK; - if (!hrOut) - hrOut = &hr; - - IPin *inputPin = nullptr; - const ScopedSafeRelease releaseInputPin { &inputPin }; - if (!findUnconnectedPin(filter, PINDIR_INPUT, &inputPin, hrOut)) - return false; - - - // Try to connect them. - *hrOut = graph->Connect(outputPin, inputPin); - if (FAILED(*hrOut)) { - qCDebug(qtDirectShowPlugin, "Unable to connect output pin to filter!"); - return false; - } - - return true; -} - -/** - * @brief DirectShowUtils::connectFilters - Attempts to connect \a filter to \a inputPin. - * @param graph - * @param filter - * @param inputPin - * @param hrOut - * @return - */ -bool DirectShowUtils::connectFilters(IGraphBuilder *graph, IBaseFilter *filter, IPin *inputPin, HRESULT *hrOut) -{ - HRESULT hr = S_OK; - if (!hrOut) - hrOut = &hr; - - IPin *outputPin = nullptr; - const ScopedSafeRelease releaseOutputPin { &outputPin }; - // Find an output pin on the upstream filter. - if (findUnconnectedPin(filter, PINDIR_OUTPUT, &outputPin, hrOut)) - return false; - - *hrOut = graph->Connect(outputPin, inputPin); - if (FAILED(*hrOut)) { - qCDebug(qtDirectShowPlugin, "Unable to connect filter to input pin!"); - return false; - } - - return true; -} - -/** - * @brief DirectShowUtils::connectFilters - Attempts to connect the \a upstreamFilter to \a downstreamFilter. - * @param graph - * @param upstreamFilter - * @param downstreamFilter - * @param autoConnect - If set to true all filters in the graph will be considered. - * @param hrOut - * @return true if the the filters were connected, false otherwise. - */ -bool DirectShowUtils::connectFilters(IGraphBuilder *graph, - IBaseFilter *upstreamFilter, - IBaseFilter *downstreamFilter, - bool autoConnect, - HRESULT *hrOut) -{ - HRESULT hr = S_OK; - if (!hrOut) - hrOut = &hr; - - const auto findAndConnect = [graph, downstreamFilter, hrOut](IBaseFilter *filter) -> bool { - IPin *outputPin = nullptr; - const ScopedSafeRelease releaseOutputPin { &outputPin }; - if (findUnconnectedPin(filter, PINDIR_OUTPUT, &outputPin, hrOut)) - return connectFilters(graph, outputPin, downstreamFilter, hrOut); - - return false; - }; - - // Try to connect to the upstream filter first. - if (findAndConnect(upstreamFilter)) - return S_OK; - - const auto getFilters = [graph, hrOut]() -> IEnumFilters * { - IEnumFilters *f = nullptr; - *hrOut = graph->EnumFilters(&f); - return f; - }; - IEnumFilters *filters = autoConnect ? getFilters() - : nullptr; - const ScopedSafeRelease releaseEnumFilters { &filters }; - if (!filters) { - qCDebug(qtDirectShowPlugin, "No filters found!"); - return false; - } - - IBaseFilter *nextFilter = nullptr; - while (S_OK == filters->Next(1, &nextFilter, 0)) { - const ScopedSafeRelease releaseNextFilter { &nextFilter }; - if (nextFilter && findAndConnect(nextFilter)) - break; - } - - return SUCCEEDED(*hrOut); -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/helpers/directshowutils.h b/src/plugins/directshow/helpers/directshowutils.h deleted file mode 100644 index 09c81c257..000000000 --- a/src/plugins/directshow/helpers/directshowutils.h +++ /dev/null @@ -1,87 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWUTILS_H -#define DIRECTSHOWUTILS_H - -#include "directshowglobal.h" - -QT_BEGIN_NAMESPACE - -namespace DirectShowUtils -{ -template -void safeRelease(T **iface) { - if (!iface) - return; - - if (!*iface) - return; - - (*iface)->Release(); - *iface = nullptr; -} - -template -struct ScopedSafeRelease -{ - T **iunknown; - ~ScopedSafeRelease() - { - DirectShowUtils::safeRelease(iunknown); - } -}; - -bool getPin(IBaseFilter *filter, PIN_DIRECTION pinDirection, IPin **pin, HRESULT *hrOut); -bool isPinConnected(IPin *pin, HRESULT *hrOut = nullptr); -bool hasPinDirection(IPin *pin, PIN_DIRECTION direction, HRESULT *hrOut = nullptr); -bool matchPin(IPin *pin, PIN_DIRECTION pinDirection, BOOL shouldBeConnected, HRESULT *hrOut = nullptr); -bool findUnconnectedPin(IBaseFilter *filter, PIN_DIRECTION pinDirection, IPin **pin, HRESULT *hrOut = nullptr); -bool connectFilters(IGraphBuilder *graph, IPin *outputPin, IBaseFilter *filter, HRESULT *hrOut = nullptr); -bool connectFilters(IGraphBuilder *graph, IBaseFilter *filter, IPin *inputPin, HRESULT *hrOut = nullptr); -bool connectFilters(IGraphBuilder *graph, - IBaseFilter *upstreamFilter, - IBaseFilter *downstreamFilter, - bool autoConnect = false, - HRESULT *hrOut = nullptr); -} - -QT_END_NAMESPACE - -#endif // DIRECTSHOWUTILS_H diff --git a/src/plugins/directshow/helpers/directshowvideobuffer.cpp b/src/plugins/directshow/helpers/directshowvideobuffer.cpp deleted file mode 100644 index 7f94da97e..000000000 --- a/src/plugins/directshow/helpers/directshowvideobuffer.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "directshowvideobuffer.h" - -QT_BEGIN_NAMESPACE - -DirectShowVideoBuffer::DirectShowVideoBuffer(IMediaSample *sample, int bytesPerLine) - : QAbstractVideoBuffer(NoHandle) - , m_sample(sample) - , m_bytesPerLine(bytesPerLine) - , m_mapMode(NotMapped) -{ - m_sample->AddRef(); -} - -DirectShowVideoBuffer::~DirectShowVideoBuffer() -{ - m_sample->Release(); -} - -uchar *DirectShowVideoBuffer::map(MapMode mode, int *numBytes, int *bytesPerLine) -{ - if (m_mapMode == NotMapped && mode != NotMapped) { - if (numBytes) - *numBytes = m_sample->GetActualDataLength(); - - if (bytesPerLine) - *bytesPerLine = m_bytesPerLine; - - BYTE *bytes = 0; - - if (m_sample->GetPointer(&bytes) == S_OK) { - m_mapMode = mode; - - return reinterpret_cast(bytes); - } - } - return 0; -} - -void DirectShowVideoBuffer::unmap() -{ - m_mapMode = NotMapped; -} - -QAbstractVideoBuffer::MapMode DirectShowVideoBuffer::mapMode() const -{ - return m_mapMode; -} - -QT_END_NAMESPACE diff --git a/src/plugins/directshow/helpers/directshowvideobuffer.h b/src/plugins/directshow/helpers/directshowvideobuffer.h deleted file mode 100644 index 85e02b53d..000000000 --- a/src/plugins/directshow/helpers/directshowvideobuffer.h +++ /dev/null @@ -1,70 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef DIRECTSHOWVIDEOBUFFER_H -#define DIRECTSHOWVIDEOBUFFER_H - -#include - -#include - -QT_BEGIN_NAMESPACE - -class DirectShowVideoBuffer : public QAbstractVideoBuffer -{ -public: - DirectShowVideoBuffer(IMediaSample *sample, int bytesPerLine); - ~DirectShowVideoBuffer(); - - IMediaSample *sample() { return m_sample; } - - uchar *map(MapMode mode, int *numBytes, int *bytesPerLine); - void unmap(); - - MapMode mapMode() const; - -private: - IMediaSample *m_sample; - int m_bytesPerLine; - MapMode m_mapMode; -}; - -QT_END_NAMESPACE - -#endif diff --git a/src/plugins/directshow/helpers/helpers.pri b/src/plugins/directshow/helpers/helpers.pri deleted file mode 100644 index ca883eeb8..000000000 --- a/src/plugins/directshow/helpers/helpers.pri +++ /dev/null @@ -1,24 +0,0 @@ -INCLUDEPATH += $$PWD - -HEADERS += \ - $$PWD/directshowbasefilter.h \ - $$PWD/directshoweventloop.h \ - $$PWD/directshowglobal.h \ - $$PWD/directshowmediatype.h \ - $$PWD/directshowmediatypeenum.h \ - $$PWD/directshowobject.h \ - $$PWD/directshowpin.h \ - $$PWD/directshowpinenum.h \ - $$PWD/directshowvideobuffer.h \ - $$PWD/directshowutils.h - -SOURCES += \ - $$PWD/directshowbasefilter.cpp \ - $$PWD/directshoweventloop.cpp \ - $$PWD/directshowmediatype.cpp \ - $$PWD/directshowmediatypeenum.cpp \ - $$PWD/directshowobject.cpp \ - $$PWD/directshowpin.cpp \ - $$PWD/directshowpinenum.cpp \ - $$PWD/directshowvideobuffer.cpp \ - $$PWD/directshowutils.cpp -- cgit v1.2.3