diff options
Diffstat (limited to 'src/plugins/directshow/player/videosurfacefilter.cpp')
-rw-r--r-- | src/plugins/directshow/player/videosurfacefilter.cpp | 631 |
1 files changed, 0 insertions, 631 deletions
diff --git a/src/plugins/directshow/player/videosurfacefilter.cpp b/src/plugins/directshow/player/videosurfacefilter.cpp deleted file mode 100644 index 6f34bc4..0000000 --- a/src/plugins/directshow/player/videosurfacefilter.cpp +++ /dev/null @@ -1,631 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). -** All rights reserved. -** Contact: Nokia Corporation (qt-info@nokia.com) -** -** This file is part of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** GNU Lesser General Public License Usage -** This file may be used under the terms of the GNU Lesser General Public -** License version 2.1 as published by the Free Software Foundation and -** appearing in the file LICENSE.LGPL included in the packaging of this -** file. Please review the following information to ensure the GNU Lesser -** General Public License version 2.1 requirements will be met: -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** In addition, as a special exception, Nokia gives you certain additional -** rights. These rights are described in the Nokia Qt LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU General -** Public License version 3.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of this -** file. Please review the following information to ensure the GNU General -** Public License version 3.0 requirements will be met: -** http://www.gnu.org/copyleft/gpl.html. -** -** Other Usage -** Alternatively, this file may be used in accordance with the terms and -** conditions contained in a signed written agreement between you and Nokia. -** -** -** -** -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "videosurfacefilter.h" - -#include "directshoweventloop.h" -#include "directshowglobal.h" -#include "directshowpinenum.h" -#include "mediasamplevideobuffer.h" - -#include <QtCore/qcoreapplication.h> -#include <QtCore/qcoreevent.h> -#include <QtCore/qthread.h> -#include <qabstractvideosurface.h> - -#include <initguid.h> - -// { e23cad72-153d-406c-bf3f-4c4b523d96f2 } -DEFINE_GUID(CLSID_VideoSurfaceFilter, -0xe23cad72, 0x153d, 0x406c, 0xbf, 0x3f, 0x4c, 0x4b, 0x52, 0x3d, 0x96, 0xf2); - -VideoSurfaceFilter::VideoSurfaceFilter( - QAbstractVideoSurface *surface, DirectShowEventLoop *loop, QObject *parent) - : QObject(parent) - , m_ref(1) - , m_state(State_Stopped) - , m_surface(surface) - , m_loop(loop) - , m_graph(0) - , m_peerPin(0) - , m_bytesPerLine(0) - , m_startResult(S_OK) - , m_pinId(QString::fromLatin1("reference")) - , m_sampleScheduler(static_cast<IPin *>(this)) -{ - connect(surface, SIGNAL(supportedFormatsChanged()), this, SLOT(supportedFormatsChanged())); - connect(&m_sampleScheduler, SIGNAL(sampleReady()), this, SLOT(sampleReady())); -} - -VideoSurfaceFilter::~VideoSurfaceFilter() -{ - Q_ASSERT(m_ref == 1); -} - -HRESULT VideoSurfaceFilter::QueryInterface(REFIID riid, void **ppvObject) -{ - // 2dd74950-a890-11d1-abe8-00a0c905f375 - static const GUID iid_IAmFilterMiscFlags = { - 0x2dd74950, 0xa890, 0x11d1, {0xab, 0xe8, 0x00, 0xa0, 0xc9, 0x05, 0xf3, 0x75} }; - - if (!ppvObject) { - return E_POINTER; - } else if (riid == IID_IUnknown - || riid == IID_IPersist - || riid == IID_IMediaFilter - || riid == IID_IBaseFilter) { - *ppvObject = static_cast<IBaseFilter *>(this); - } else if (riid == iid_IAmFilterMiscFlags) { - *ppvObject = static_cast<IAMFilterMiscFlags *>(this); - } else if (riid == IID_IPin) { - *ppvObject = static_cast<IPin *>(this); - } else if (riid == IID_IMemInputPin) { - *ppvObject = static_cast<IMemInputPin *>(&m_sampleScheduler); - } else { - *ppvObject = 0; - - return E_NOINTERFACE; - } - - AddRef(); - - return S_OK; -} - -ULONG VideoSurfaceFilter::AddRef() -{ - return InterlockedIncrement(&m_ref); -} - -ULONG VideoSurfaceFilter::Release() -{ - ULONG ref = InterlockedDecrement(&m_ref); - - Q_ASSERT(ref != 0); - - return ref; -} - -HRESULT VideoSurfaceFilter::GetClassID(CLSID *pClassID) -{ - *pClassID = CLSID_VideoSurfaceFilter; - - return S_OK; -} - -HRESULT VideoSurfaceFilter::Run(REFERENCE_TIME tStart) -{ - m_state = State_Running; - - m_sampleScheduler.run(tStart); - - return S_OK; -} - -HRESULT VideoSurfaceFilter::Pause() -{ - m_state = State_Paused; - - m_sampleScheduler.pause(); - - return S_OK; -} - -HRESULT VideoSurfaceFilter::Stop() -{ - m_state = State_Stopped; - - m_sampleScheduler.stop(); - - return S_OK; -} - -HRESULT VideoSurfaceFilter::GetState(DWORD dwMilliSecsTimeout, FILTER_STATE *pState) -{ - if (!pState) - return E_POINTER; - - *pState = m_state; - - return S_OK; -} - -HRESULT VideoSurfaceFilter::SetSyncSource(IReferenceClock *pClock) -{ - - m_sampleScheduler.setClock(pClock); - - return S_OK; -} - -HRESULT VideoSurfaceFilter::GetSyncSource(IReferenceClock **ppClock) -{ - if (!ppClock) { - return E_POINTER; - } else { - *ppClock = m_sampleScheduler.clock(); - - if (*ppClock) { - (*ppClock)->AddRef(); - - return S_OK; - } else { - return S_FALSE; - } - } -} - -HRESULT VideoSurfaceFilter::EnumPins(IEnumPins **ppEnum) -{ - if (ppEnum) { - *ppEnum = new DirectShowPinEnum(QList<IPin *>() << this); - - return S_OK; - } else { - return E_POINTER; - } -} - -HRESULT VideoSurfaceFilter::FindPin(LPCWSTR pId, IPin **ppPin) -{ - if (!ppPin || !pId) { - return E_POINTER; - } else if (QString::fromWCharArray(pId) == m_pinId) { - AddRef(); - - *ppPin = this; - - return S_OK; - } else { - return VFW_E_NOT_FOUND; - } -} - -HRESULT VideoSurfaceFilter::JoinFilterGraph(IFilterGraph *pGraph, LPCWSTR pName) -{ - m_graph = pGraph; - m_name = QString::fromWCharArray(pName); - - return S_OK; -} - -HRESULT VideoSurfaceFilter::QueryFilterInfo(FILTER_INFO *pInfo) -{ - if (pInfo) { - QString name = m_name; - - 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; - } else { - return E_POINTER; - } -} - -HRESULT VideoSurfaceFilter::QueryVendorInfo(LPWSTR *pVendorInfo) -{ - Q_UNUSED(pVendorInfo); - - return E_NOTIMPL; -} - -ULONG VideoSurfaceFilter::GetMiscFlags() -{ - return AM_FILTER_MISC_FLAGS_IS_RENDERER; -} - - -HRESULT VideoSurfaceFilter::Connect(IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) -{ - // This is an input pin, you shouldn't be calling Connect on it. - return E_POINTER; -} - -HRESULT VideoSurfaceFilter::ReceiveConnection(IPin *pConnector, const AM_MEDIA_TYPE *pmt) -{ - if (!pConnector) { - return E_POINTER; - } else if (!pmt) { - return E_POINTER; - } else { - HRESULT hr; - QMutexLocker locker(&m_mutex); - - if (m_peerPin) { - hr = VFW_E_ALREADY_CONNECTED; - } else if (pmt->majortype != MEDIATYPE_Video) { - hr = VFW_E_TYPE_NOT_ACCEPTED; - } else { - m_surfaceFormat = DirectShowMediaType::formatFromType(*pmt); - m_bytesPerLine = DirectShowMediaType::bytesPerLine(m_surfaceFormat); - - if (thread() == QThread::currentThread()) { - hr = start(); - } else { - m_loop->postEvent(this, new QEvent(QEvent::Type(StartSurface))); - - m_wait.wait(&m_mutex); - - hr = m_startResult; - } - } - if (hr == S_OK) { - m_peerPin = pConnector; - m_peerPin->AddRef(); - - DirectShowMediaType::copy(&m_mediaType, *pmt); - } - return hr; - } -} - -HRESULT VideoSurfaceFilter::start() -{ - if (!m_surface->isFormatSupported(m_surfaceFormat)) { - return VFW_E_TYPE_NOT_ACCEPTED; - } - if (!m_surface->start(m_surfaceFormat)) { - return VFW_E_TYPE_NOT_ACCEPTED; - } else { - return S_OK; - } -} - -HRESULT VideoSurfaceFilter::Disconnect() -{ - QMutexLocker locker(&m_mutex); - - if (!m_peerPin) - return S_FALSE; - - if (thread() == QThread::currentThread()) { - stop(); - } else { - m_loop->postEvent(this, new QEvent(QEvent::Type(StopSurface))); - - m_wait.wait(&m_mutex); - } - - m_mediaType.clear(); - - m_sampleScheduler.NotifyAllocator(0, FALSE); - - m_peerPin->Release(); - m_peerPin = 0; - - return S_OK; -} - -void VideoSurfaceFilter::stop() -{ - m_surface->stop(); -} - -HRESULT VideoSurfaceFilter::ConnectedTo(IPin **ppPin) -{ - if (!ppPin) { - return E_POINTER; - } else { - QMutexLocker locker(&m_mutex); - - if (!m_peerPin) { - return VFW_E_NOT_CONNECTED; - } else { - m_peerPin->AddRef(); - - *ppPin = m_peerPin; - - return S_OK; - } - } -} - -HRESULT VideoSurfaceFilter::ConnectionMediaType(AM_MEDIA_TYPE *pmt) -{ - if (!pmt) { - return E_POINTER; - } else { - QMutexLocker locker(&m_mutex); - - if (!m_peerPin) { - return VFW_E_NOT_CONNECTED; - } else { - DirectShowMediaType::copy(pmt, m_mediaType); - - return S_OK; - } - } -} - -HRESULT VideoSurfaceFilter::QueryPinInfo(PIN_INFO *pInfo) -{ - if (!pInfo) { - return E_POINTER; - } else { - AddRef(); - - pInfo->pFilter = this; - pInfo->dir = PINDIR_INPUT; - - const int bytes = qMin(MAX_FILTER_NAME, (m_pinId.length() + 1) * 2); - - qMemCopy(pInfo->achName, m_pinId.utf16(), bytes); - - return S_OK; - } -} - -HRESULT VideoSurfaceFilter::QueryId(LPWSTR *Id) -{ - if (!Id) { - return E_POINTER; - } else { - const int bytes = (m_pinId.length() + 1) * 2; - - *Id = static_cast<LPWSTR>(::CoTaskMemAlloc(bytes)); - - qMemCopy(*Id, m_pinId.utf16(), bytes); - - return S_OK; - } -} - -HRESULT VideoSurfaceFilter::QueryAccept(const AM_MEDIA_TYPE *pmt) -{ - return !m_surface->isFormatSupported(DirectShowMediaType::formatFromType(*pmt)) - ? S_OK - : S_FALSE; -} - -HRESULT VideoSurfaceFilter::EnumMediaTypes(IEnumMediaTypes **ppEnum) -{ - if (!ppEnum) { - return E_POINTER; - } else { - QMutexLocker locker(&m_mutex); - - *ppEnum = createMediaTypeEnum(); - - return S_OK; - } -} - -HRESULT VideoSurfaceFilter::QueryInternalConnections(IPin **apPin, ULONG *nPin) -{ - Q_UNUSED(apPin); - Q_UNUSED(nPin); - - return E_NOTIMPL; -} - -HRESULT VideoSurfaceFilter::EndOfStream() -{ - QMutexLocker locker(&m_mutex); - - if (!m_sampleScheduler.scheduleEndOfStream()) { - if (IMediaEventSink *sink = com_cast<IMediaEventSink>(m_graph, IID_IMediaEventSink)) { - sink->Notify( - EC_COMPLETE, - S_OK, - reinterpret_cast<LONG_PTR>(static_cast<IBaseFilter *>(this))); - sink->Release(); - } - } - - return S_OK; -} - -HRESULT VideoSurfaceFilter::BeginFlush() -{ - QMutexLocker locker(&m_mutex); - - m_sampleScheduler.setFlushing(true); - - if (thread() == QThread::currentThread()) { - flush(); - } else { - m_loop->postEvent(this, new QEvent(QEvent::Type(FlushSurface))); - - m_wait.wait(&m_mutex); - } - - return S_OK; -} - -HRESULT VideoSurfaceFilter::EndFlush() -{ - QMutexLocker locker(&m_mutex); - - m_sampleScheduler.setFlushing(false); - - return S_OK; -} - -void VideoSurfaceFilter::flush() -{ - m_surface->present(QVideoFrame()); - - m_wait.wakeAll(); -} - -HRESULT VideoSurfaceFilter::NewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) -{ - Q_UNUSED(tStart); - Q_UNUSED(tStop); - Q_UNUSED(dRate); - - return S_OK; -} - -HRESULT VideoSurfaceFilter::QueryDirection(PIN_DIRECTION *pPinDir) -{ - if (!pPinDir) { - return E_POINTER; - } else { - *pPinDir = PINDIR_INPUT; - - return S_OK; - } -} - -int VideoSurfaceFilter::currentMediaTypeToken() -{ - QMutexLocker locker(&m_mutex); - - return DirectShowMediaTypeList::currentMediaTypeToken(); -} - -HRESULT VideoSurfaceFilter::nextMediaType( - int token, int *index, ULONG count, AM_MEDIA_TYPE **types, ULONG *fetchedCount) -{ - QMutexLocker locker(&m_mutex); - - return DirectShowMediaTypeList::nextMediaType(token, index, count, types, fetchedCount); - -} - -HRESULT VideoSurfaceFilter::skipMediaType(int token, int *index, ULONG count) -{ - QMutexLocker locker(&m_mutex); - - return DirectShowMediaTypeList::skipMediaType(token, index, count); -} - -HRESULT VideoSurfaceFilter::cloneMediaType(int token, int index, IEnumMediaTypes **enumeration) -{ - QMutexLocker locker(&m_mutex); - - return DirectShowMediaTypeList::cloneMediaType(token, index, enumeration); -} - -void VideoSurfaceFilter::customEvent(QEvent *event) -{ - if (event->type() == StartSurface) { - QMutexLocker locker(&m_mutex); - - m_startResult = start(); - - m_wait.wakeAll(); - } else if (event->type() == StopSurface) { - QMutexLocker locker(&m_mutex); - - stop(); - - m_wait.wakeAll(); - } else if (event->type() == FlushSurface) { - QMutexLocker locker(&m_mutex); - - flush(); - - m_wait.wakeAll(); - } else { - QObject::customEvent(event); - } -} - -void VideoSurfaceFilter::supportedFormatsChanged() -{ - QMutexLocker locker(&m_mutex); - - // MEDIASUBTYPE_None; - static const GUID none = { - 0xe436eb8e, 0x524f, 0x11ce, {0x9f, 0x53, 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70} }; - - QList<QVideoFrame::PixelFormat> formats = m_surface->supportedPixelFormats(); - - QVector<AM_MEDIA_TYPE> mediaTypes; - mediaTypes.reserve(formats.count()); - - AM_MEDIA_TYPE type; - type.majortype = MEDIATYPE_Video; - type.bFixedSizeSamples = TRUE; - type.bTemporalCompression = FALSE; - type.lSampleSize = 0; - type.formattype = GUID_NULL; - type.pUnk = 0; - type.cbFormat = 0; - type.pbFormat = 0; - - foreach (QVideoFrame::PixelFormat format, formats) { - type.subtype = DirectShowMediaType::convertPixelFormat(format); - - if (type.subtype != none) - mediaTypes.append(type); - } - - setMediaTypes(mediaTypes); -} - -void VideoSurfaceFilter::sampleReady() -{ - bool eos = false; - - IMediaSample *sample = m_sampleScheduler.takeSample(&eos); - - if (sample) { - m_surface->present(QVideoFrame( - new MediaSampleVideoBuffer(sample, m_bytesPerLine), - m_surfaceFormat.frameSize(), - m_surfaceFormat.pixelFormat())); - - sample->Release(); - - if (eos) { - if (IMediaEventSink *sink = com_cast<IMediaEventSink>(m_graph, IID_IMediaEventSink)) { - sink->Notify( - EC_COMPLETE, - S_OK, - reinterpret_cast<LONG_PTR>(static_cast<IBaseFilter *>(this))); - sink->Release(); - } - } - } -} - |