From 9402c733f010a32d2fd660664042a3d36c8b55e7 Mon Sep 17 00:00:00 2001 From: Maarten Lankhorst Date: Tue, 22 Jul 2008 14:01:03 -0700 Subject: [PATCH] qcap: Make VfwCapture use the directshow wine base classes --- dlls/qcap/Makefile.in | 5 +- dlls/qcap/enummedia.c | 267 ------------------------------ dlls/qcap/enumpins.c | 186 --------------------- dlls/qcap/pin.c | 423 ------------------------------------------------ dlls/qcap/pin.h | 82 ---------- dlls/qcap/qcap_main.h | 24 +--- dlls/qcap/v4l.c | 1 - dlls/qcap/vfwcapture.c | 29 ++-- 8 files changed, 21 insertions(+), 996 deletions(-) delete mode 100644 dlls/qcap/enummedia.c delete mode 100644 dlls/qcap/enumpins.c delete mode 100644 dlls/qcap/pin.c delete mode 100644 dlls/qcap/pin.h diff --git a/dlls/qcap/Makefile.in b/dlls/qcap/Makefile.in index c273bcb..44479e6 100644 --- a/dlls/qcap/Makefile.in +++ b/dlls/qcap/Makefile.in @@ -3,14 +3,11 @@ TOPOBJDIR = ../.. SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = qcap.dll -IMPORTS = strmiids uuid ole32 gdi32 advapi32 kernel32 +IMPORTS = strmiids strmbase uuid ole32 gdi32 advapi32 kernel32 C_SRCS = \ capturegraph.c \ dllsetup.c \ - enummedia.c \ - enumpins.c \ - pin.c \ qcap_main.c \ v4l.c \ vfwcapture.c \ diff --git a/dlls/qcap/enummedia.c b/dlls/qcap/enummedia.c deleted file mode 100644 index 87a6e2d..0000000 --- a/dlls/qcap/enummedia.c +++ /dev/null @@ -1,267 +0,0 @@ -/* - * Implementation of IEnumMediaTypes Interface - * - * Copyright 2003 Robert Shearman - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include - -#define COBJMACROS - -#include "windef.h" -#include "winbase.h" -#include "wtypes.h" -#include "wingdi.h" -#include "winuser.h" -#include "dshow.h" - -#include "qcap_main.h" - -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(qcap); - -HRESULT CopyMediaType(AM_MEDIA_TYPE * pDest, const AM_MEDIA_TYPE *pSrc) -{ - *pDest = *pSrc; - if (!pSrc->pbFormat) return S_OK; - if (!(pDest->pbFormat = CoTaskMemAlloc(pSrc->cbFormat))) - return E_OUTOFMEMORY; - memcpy(pDest->pbFormat, pSrc->pbFormat, pSrc->cbFormat); - return S_OK; -} - -void FreeMediaType(AM_MEDIA_TYPE * pMediaType) -{ - CoTaskMemFree(pMediaType->pbFormat); - pMediaType->pbFormat = NULL; - - if (pMediaType->pUnk) - { - IUnknown_Release(pMediaType->pUnk); - pMediaType->pUnk = NULL; - } -} - -void DeleteMediaType(AM_MEDIA_TYPE * pMediaType) -{ - FreeMediaType(pMediaType); - CoTaskMemFree(pMediaType); -} - -BOOL CompareMediaTypes(const AM_MEDIA_TYPE * pmt1, const AM_MEDIA_TYPE * pmt2, - BOOL bWildcards) -{ - TRACE("pmt1: "); - dump_AM_MEDIA_TYPE(pmt1); - TRACE("pmt2: "); - dump_AM_MEDIA_TYPE(pmt2); - return (((bWildcards && (IsEqualGUID(&pmt1->majortype, &GUID_NULL) || - IsEqualGUID(&pmt2->majortype, &GUID_NULL))) || - IsEqualGUID(&pmt1->majortype, &pmt2->majortype)) && - ((bWildcards && (IsEqualGUID(&pmt1->subtype, &GUID_NULL) || - IsEqualGUID(&pmt2->subtype, &GUID_NULL))) || - IsEqualGUID(&pmt1->subtype, &pmt2->subtype))); -} - -void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE * pmt) -{ - if (!pmt) - return; - TRACE("\t%s\n\t%s\n\t...\n\t%s\n", debugstr_guid(&pmt->majortype), - debugstr_guid(&pmt->subtype), debugstr_guid(&pmt->formattype)); -} - -typedef struct IEnumMediaTypesImpl -{ - const IEnumMediaTypesVtbl * lpVtbl; - LONG refCount; - ENUMMEDIADETAILS enumMediaDetails; - ULONG uIndex; -} IEnumMediaTypesImpl; - -static const struct IEnumMediaTypesVtbl IEnumMediaTypesImpl_Vtbl; - -HRESULT IEnumMediaTypesImpl_Construct(const ENUMMEDIADETAILS * pDetails, - IEnumMediaTypes ** ppEnum) -{ - ULONG i; - IEnumMediaTypesImpl * pEnumMediaTypes = CoTaskMemAlloc(sizeof(IEnumMediaTypesImpl)); - - if (!pEnumMediaTypes) - { - *ppEnum = NULL; - return E_OUTOFMEMORY; - } - ObjectRefCount(TRUE); - pEnumMediaTypes->lpVtbl = &IEnumMediaTypesImpl_Vtbl; - pEnumMediaTypes->refCount = 1; - pEnumMediaTypes->uIndex = 0; - pEnumMediaTypes->enumMediaDetails.cMediaTypes = pDetails->cMediaTypes; - pEnumMediaTypes->enumMediaDetails.pMediaTypes = - CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE) * pDetails->cMediaTypes); - for (i = 0; i < pDetails->cMediaTypes; i++) - if (FAILED(CopyMediaType(&pEnumMediaTypes->enumMediaDetails.pMediaTypes[i], &pDetails->pMediaTypes[i]))) { - while (i--) CoTaskMemFree(pEnumMediaTypes->enumMediaDetails.pMediaTypes[i].pbFormat); - CoTaskMemFree(pEnumMediaTypes->enumMediaDetails.pMediaTypes); - return E_OUTOFMEMORY; - } - *ppEnum = (IEnumMediaTypes *)(&pEnumMediaTypes->lpVtbl); - return S_OK; -} - -static HRESULT WINAPI IEnumMediaTypesImpl_QueryInterface(IEnumMediaTypes * iface, - REFIID riid, - LPVOID * ppv) -{ - TRACE("(%s, %p)\n", debugstr_guid(riid), ppv); - - *ppv = NULL; - - if (IsEqualIID(riid, &IID_IUnknown)) - *ppv = (LPVOID)iface; - else if (IsEqualIID(riid, &IID_IEnumMediaTypes)) - *ppv = (LPVOID)iface; - - if (*ppv) - { - IUnknown_AddRef((IUnknown *)(*ppv)); - return S_OK; - } - - FIXME("No interface for %s!\n", debugstr_guid(riid)); - - return E_NOINTERFACE; -} - -static ULONG WINAPI IEnumMediaTypesImpl_AddRef(IEnumMediaTypes * iface) -{ - IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface; - ULONG refCount = InterlockedIncrement(&This->refCount); - - TRACE("()\n"); - - return refCount; -} - -static ULONG WINAPI IEnumMediaTypesImpl_Release(IEnumMediaTypes * iface) -{ - IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface; - ULONG refCount = InterlockedDecrement(&This->refCount); - - TRACE("()\n"); - - if (!refCount) - { - int i; - for (i = 0; i < This->enumMediaDetails.cMediaTypes; i++) - if (This->enumMediaDetails.pMediaTypes[i].pbFormat) - CoTaskMemFree(This->enumMediaDetails.pMediaTypes[i].pbFormat); - CoTaskMemFree(This->enumMediaDetails.pMediaTypes); - CoTaskMemFree(This); - ObjectRefCount(FALSE); - } - return refCount; -} - -static HRESULT WINAPI IEnumMediaTypesImpl_Next(IEnumMediaTypes * iface, - ULONG cMediaTypes, - AM_MEDIA_TYPE ** ppMediaTypes, - ULONG * pcFetched) -{ - ULONG cFetched; - IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface; - - cFetched = min(This->enumMediaDetails.cMediaTypes, - This->uIndex + cMediaTypes) - This->uIndex; - - TRACE("(%u, %p, %p)\n", cMediaTypes, ppMediaTypes, pcFetched); - TRACE("Next uIndex: %u, cFetched: %u\n", This->uIndex, cFetched); - - if (cFetched > 0) - { - ULONG i; - *ppMediaTypes = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE) * cFetched); - for (i = 0; i < cFetched; i++) - if (FAILED(CopyMediaType(&(*ppMediaTypes)[i], &This->enumMediaDetails.pMediaTypes[This->uIndex + i]))) { - while (i--) - CoTaskMemFree((*ppMediaTypes)[i].pbFormat); - CoTaskMemFree(*ppMediaTypes); - *ppMediaTypes = NULL; - return E_OUTOFMEMORY; - } - } - - if ((cMediaTypes != 1) || pcFetched) - *pcFetched = cFetched; - - This->uIndex += cFetched; - - if (cFetched != cMediaTypes) - return S_FALSE; - return S_OK; -} - -static HRESULT WINAPI IEnumMediaTypesImpl_Skip(IEnumMediaTypes * iface, - ULONG cMediaTypes) -{ - IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface; - - TRACE("(%u)\n", cMediaTypes); - - if (This->uIndex + cMediaTypes < This->enumMediaDetails.cMediaTypes) - { - This->uIndex += cMediaTypes; - return S_OK; - } - return S_FALSE; -} - -static HRESULT WINAPI IEnumMediaTypesImpl_Reset(IEnumMediaTypes * iface) -{ - IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface; - - TRACE("()\n"); - - This->uIndex = 0; - return S_OK; -} - -static HRESULT WINAPI IEnumMediaTypesImpl_Clone(IEnumMediaTypes * iface, - IEnumMediaTypes ** ppEnum) -{ - HRESULT hr; - IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface; - - TRACE("(%p)\n", ppEnum); - - hr = IEnumMediaTypesImpl_Construct(&This->enumMediaDetails, ppEnum); - if (FAILED(hr)) - return hr; - return IEnumMediaTypes_Skip(*ppEnum, This->uIndex); -} - -static const IEnumMediaTypesVtbl IEnumMediaTypesImpl_Vtbl = -{ - IEnumMediaTypesImpl_QueryInterface, - IEnumMediaTypesImpl_AddRef, - IEnumMediaTypesImpl_Release, - IEnumMediaTypesImpl_Next, - IEnumMediaTypesImpl_Skip, - IEnumMediaTypesImpl_Reset, - IEnumMediaTypesImpl_Clone -}; diff --git a/dlls/qcap/enumpins.c b/dlls/qcap/enumpins.c deleted file mode 100644 index c57c043..0000000 --- a/dlls/qcap/enumpins.c +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Implementation of IEnumPins Interface - * - * Copyright 2003 Robert Shearman - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include - -#define COBJMACROS - -#include "windef.h" -#include "winbase.h" -#include "wtypes.h" -#include "wingdi.h" -#include "winuser.h" -#include "dshow.h" - -#include "qcap_main.h" - -#include "wine/debug.h" - -WINE_DEFAULT_DEBUG_CHANNEL(qcap); - -typedef struct IEnumPinsImpl -{ - const IEnumPinsVtbl * lpVtbl; - LONG refCount; - ENUMPINDETAILS enumPinDetails; - ULONG uIndex; -} IEnumPinsImpl; - -static const struct IEnumPinsVtbl IEnumPinsImpl_Vtbl; - -HRESULT IEnumPinsImpl_Construct(const ENUMPINDETAILS * pDetails, IEnumPins ** ppEnum) -{ - IEnumPinsImpl * pEnumPins = CoTaskMemAlloc(sizeof(IEnumPinsImpl)); - if (!pEnumPins) - { - *ppEnum = NULL; - return E_OUTOFMEMORY; - } - pEnumPins->lpVtbl = &IEnumPinsImpl_Vtbl; - pEnumPins->refCount = 1; - pEnumPins->uIndex = 0; - pEnumPins->enumPinDetails = *pDetails; - *ppEnum = (IEnumPins *)(&pEnumPins->lpVtbl); - ObjectRefCount(TRUE); - return S_OK; -} - -static HRESULT WINAPI IEnumPinsImpl_QueryInterface(IEnumPins * iface, REFIID riid, LPVOID * ppv) -{ - TRACE("(%s, %p)\n", debugstr_guid(riid), ppv); - - *ppv = NULL; - - if (IsEqualIID(riid, &IID_IUnknown)) - *ppv = (LPVOID)iface; - else if (IsEqualIID(riid, &IID_IEnumPins)) - *ppv = (LPVOID)iface; - - if (*ppv) - { - IUnknown_AddRef((IUnknown *)(*ppv)); - return S_OK; - } - - FIXME("No interface for %s!\n", debugstr_guid(riid)); - - return E_NOINTERFACE; -} - -static ULONG WINAPI IEnumPinsImpl_AddRef(IEnumPins * iface) -{ - IEnumPinsImpl *This = (IEnumPinsImpl *)iface; - ULONG refCount = InterlockedIncrement(&This->refCount); - - TRACE("()\n"); - - return refCount; -} - -static ULONG WINAPI IEnumPinsImpl_Release(IEnumPins * iface) -{ - IEnumPinsImpl *This = (IEnumPinsImpl *)iface; - ULONG refCount = InterlockedDecrement(&This->refCount); - - TRACE("()\n"); - - if (!refCount) - { - CoTaskMemFree(This); - ObjectRefCount(FALSE); - } - return refCount; -} - -static HRESULT WINAPI IEnumPinsImpl_Next(IEnumPins * iface, ULONG cPins, IPin ** ppPins, ULONG * pcFetched) -{ - ULONG cFetched; - IEnumPinsImpl *This = (IEnumPinsImpl *)iface; - - cFetched = min(This->enumPinDetails.cPins, This->uIndex + cPins) - This->uIndex; - - TRACE("(%u, %p, %p)\n", cPins, ppPins, pcFetched); - - if (cFetched > 0) - { - ULONG i; - for (i = 0; i < cFetched; i++) { - IPin_AddRef(This->enumPinDetails.ppPins[This->uIndex + i]); - ppPins[i] = This->enumPinDetails.ppPins[This->uIndex + i]; - } - } - - if ((cPins != 1) || pcFetched) - *pcFetched = cFetched; - - This->uIndex += cFetched; - - if (cFetched != cPins) - return S_FALSE; - return S_OK; -} - -static HRESULT WINAPI IEnumPinsImpl_Skip(IEnumPins * iface, ULONG cPins) -{ - IEnumPinsImpl *This = (IEnumPinsImpl *)iface; - - TRACE("(%u)\n", cPins); - - if (This->uIndex + cPins < This->enumPinDetails.cPins) - { - This->uIndex += cPins; - return S_OK; - } - return S_FALSE; -} - -static HRESULT WINAPI IEnumPinsImpl_Reset(IEnumPins * iface) -{ - IEnumPinsImpl *This = (IEnumPinsImpl *)iface; - - TRACE("IEnumPinsImpl::Reset()\n"); - - This->uIndex = 0; - return S_OK; -} - -static HRESULT WINAPI IEnumPinsImpl_Clone(IEnumPins * iface, IEnumPins ** ppEnum) -{ - HRESULT hr; - IEnumPinsImpl *This = (IEnumPinsImpl *)iface; - - TRACE("(%p)\n", ppEnum); - - hr = IEnumPinsImpl_Construct(&This->enumPinDetails, ppEnum); - if (FAILED(hr)) - return hr; - return IEnumPins_Skip(*ppEnum, This->uIndex); -} - -static const IEnumPinsVtbl IEnumPinsImpl_Vtbl = -{ - IEnumPinsImpl_QueryInterface, - IEnumPinsImpl_AddRef, - IEnumPinsImpl_Release, - IEnumPinsImpl_Next, - IEnumPinsImpl_Skip, - IEnumPinsImpl_Reset, - IEnumPinsImpl_Clone -}; diff --git a/dlls/qcap/pin.c b/dlls/qcap/pin.c deleted file mode 100644 index 44ce5e8..0000000 --- a/dlls/qcap/pin.c +++ /dev/null @@ -1,423 +0,0 @@ -/* - * Generic Implementation of IPin Interface - * - * Copyright 2003 Robert Shearman - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include - -#define COBJMACROS - -#include "windef.h" -#include "winbase.h" -#include "wtypes.h" -#include "wingdi.h" -#include "winuser.h" -#include "dshow.h" - -#include "qcap_main.h" -#include "pin.h" - -#include "wine/debug.h" -#include "wine/unicode.h" -#include "uuids.h" -#include "vfwmsgs.h" -#include - -WINE_DEFAULT_DEBUG_CHANNEL(qcap); - -#define ALIGNDOWN(value,boundary) ((value) & ~(boundary-1)) -#define ALIGNUP(value,boundary) (ALIGNDOWN(value - 1, boundary) + boundary) - -static void Copy_PinInfo(PIN_INFO * pDest, const PIN_INFO * pSrc) -{ - /* Tempting to just do a memcpy, but the name field is - 128 characters long! We will probably never exceed 10 - most of the time, so we are better off copying - each field manually */ - strcpyW(pDest->achName, pSrc->achName); - pDest->dir = pSrc->dir; - pDest->pFilter = pSrc->pFilter; -} - -HRESULT WINAPI IPinImpl_ConnectedTo(IPin * iface, IPin ** ppPin) -{ - HRESULT hr; - IPinImpl *This = (IPinImpl *)iface; - -/* TRACE("(%p)\n", ppPin);*/ - - EnterCriticalSection(This->pCritSec); - { - if (This->pConnectedTo) - { - *ppPin = This->pConnectedTo; - IPin_AddRef(*ppPin); - hr = S_OK; - } - else - hr = VFW_E_NOT_CONNECTED; - } - LeaveCriticalSection(This->pCritSec); - - return hr; -} - -HRESULT WINAPI IPinImpl_ConnectionMediaType(IPin * iface, AM_MEDIA_TYPE * pmt) -{ - HRESULT hr; - IPinImpl *This = (IPinImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, pmt); - - EnterCriticalSection(This->pCritSec); - { - if (This->pConnectedTo) - { - CopyMediaType(pmt, &This->mtCurrent); - hr = S_OK; - } - else - { - ZeroMemory(pmt, sizeof(*pmt)); - hr = VFW_E_NOT_CONNECTED; - } - } - LeaveCriticalSection(This->pCritSec); - - return hr; -} - -HRESULT WINAPI IPinImpl_QueryPinInfo(IPin * iface, PIN_INFO * pInfo) -{ - IPinImpl *This = (IPinImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, pInfo); - - Copy_PinInfo(pInfo, &This->pinInfo); - IBaseFilter_AddRef(pInfo->pFilter); - - return S_OK; -} - -HRESULT WINAPI IPinImpl_QueryDirection(IPin * iface, PIN_DIRECTION * pPinDir) -{ - IPinImpl *This = (IPinImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, pPinDir); - - *pPinDir = This->pinInfo.dir; - - return S_OK; -} - -HRESULT WINAPI IPinImpl_QueryId(IPin * iface, LPWSTR * Id) -{ - IPinImpl *This = (IPinImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, Id); - - *Id = CoTaskMemAlloc((strlenW(This->pinInfo.achName) + 1) * sizeof(WCHAR)); - if (!*Id) - return E_OUTOFMEMORY; - - strcpyW(*Id, This->pinInfo.achName); - - return S_OK; -} - -HRESULT WINAPI IPinImpl_QueryAccept(IPin * iface, const AM_MEDIA_TYPE * pmt) -{ - IPinImpl *This = (IPinImpl *)iface; - - TRACE("(%p/%p)->(%p)\n", This, iface, pmt); - - if (!This->fnQueryAccept) return S_OK; - - return (This->fnQueryAccept(This->pUserData, pmt) == S_OK ? S_OK : S_FALSE); -} - -HRESULT WINAPI IPinImpl_QueryInternalConnections(IPin * iface, IPin ** apPin, ULONG * cPin) -{ - IPinImpl *This = (IPinImpl *)iface; - - TRACE("(%p/%p)->(%p, %p)\n", This, iface, apPin, cPin); - - return E_NOTIMPL; /* to tell caller that all input pins connected to all output pins */ -} - -/* Function called as a helper to IPin_Connect */ -/* specific AM_MEDIA_TYPE - it cannot be NULL */ -/* NOTE: not part of standard interface */ -static HRESULT OutputPin_ConnectSpecific(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) -{ - OutputPin *This = (OutputPin *)iface; - HRESULT hr; - IMemAllocator * pMemAlloc = NULL; - ALLOCATOR_PROPERTIES actual; /* FIXME: should we put the actual props back in to This? */ - - TRACE("(%p, %p)\n", pReceivePin, pmt); - dump_AM_MEDIA_TYPE(pmt); - - /* FIXME: call queryacceptproc */ - - This->pin.pConnectedTo = pReceivePin; - IPin_AddRef(pReceivePin); - CopyMediaType(&This->pin.mtCurrent, pmt); - - hr = IPin_ReceiveConnection(pReceivePin, iface, pmt); - - /* get the IMemInputPin interface we will use to deliver samples to the - * connected pin */ - if (SUCCEEDED(hr)) - { - hr = IPin_QueryInterface(pReceivePin, &IID_IMemInputPin, (LPVOID)&This->pMemInputPin); - - if (SUCCEEDED(hr)) - hr = IMemInputPin_GetAllocator(This->pMemInputPin, &pMemAlloc); - - if (hr == VFW_E_NO_ALLOCATOR) - { - /* Input pin provides no allocator, use standard memory allocator */ - hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER, &IID_IMemAllocator, (LPVOID*)&pMemAlloc); - - if (SUCCEEDED(hr)) - { - hr = IMemInputPin_NotifyAllocator(This->pMemInputPin, pMemAlloc, FALSE); - } - } - - if (SUCCEEDED(hr)) - hr = IMemAllocator_SetProperties(pMemAlloc, &This->allocProps, &actual); - - if (pMemAlloc) - IMemAllocator_Release(pMemAlloc); - - /* break connection if we couldn't get the allocator */ - if (FAILED(hr)) - IPin_Disconnect(pReceivePin); - } - - if (FAILED(hr)) - { - IPin_Release(This->pin.pConnectedTo); - This->pin.pConnectedTo = NULL; - DeleteMediaType(&This->pin.mtCurrent); - } - - TRACE(" -- %x\n", hr); - return hr; -} - -HRESULT OutputPin_Init(const PIN_INFO * pPinInfo, const ALLOCATOR_PROPERTIES * props, - LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, - LPCRITICAL_SECTION pCritSec, OutputPin * pPinImpl) -{ - TRACE("\n"); - - /* Common attributes */ - pPinImpl->pin.refCount = 1; - pPinImpl->pin.pConnectedTo = NULL; - pPinImpl->pin.fnQueryAccept = pQueryAccept; - pPinImpl->pin.pUserData = pUserData; - pPinImpl->pin.pCritSec = pCritSec; - Copy_PinInfo(&pPinImpl->pin.pinInfo, pPinInfo); - - /* Output pin attributes */ - pPinImpl->pMemInputPin = NULL; - pPinImpl->pConnectSpecific = OutputPin_ConnectSpecific; - if (props) - { - pPinImpl->allocProps = *props; - if (pPinImpl->allocProps.cbAlign == 0) - pPinImpl->allocProps.cbAlign = 1; - } - else - ZeroMemory(&pPinImpl->allocProps, sizeof(pPinImpl->allocProps)); - - return S_OK; -} - -HRESULT WINAPI OutputPin_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) -{ - HRESULT hr; - OutputPin *This = (OutputPin *)iface; - - TRACE("(%p/%p)->(%p, %p)\n", This, iface, pReceivePin, pmt); - dump_AM_MEDIA_TYPE(pmt); - - /* If we try to connect to ourself, we will definitely deadlock. - * There are other cases where we could deadlock too, but this - * catches the obvious case */ - assert(pReceivePin != iface); - - EnterCriticalSection(This->pin.pCritSec); - { - /* if we have been a specific type to connect with, then we can either connect - * with that or fail. We cannot choose different AM_MEDIA_TYPE */ - if (pmt && !IsEqualGUID(&pmt->majortype, &GUID_NULL) && !IsEqualGUID(&pmt->subtype, &GUID_NULL)) - hr = This->pConnectSpecific(iface, pReceivePin, pmt); - else - { - /* negotiate media type */ - - IEnumMediaTypes * pEnumCandidates; - AM_MEDIA_TYPE * pmtCandidate; /* Candidate media type */ - - if (SUCCEEDED(hr = IPin_EnumMediaTypes(iface, &pEnumCandidates))) - { - hr = VFW_E_NO_ACCEPTABLE_TYPES; /* Assume the worst, but set to S_OK if connected successfully */ - - /* try this filter's media types first */ - while (S_OK == IEnumMediaTypes_Next(pEnumCandidates, 1, &pmtCandidate, NULL)) - { - if (( !pmt || CompareMediaTypes(pmt, pmtCandidate, TRUE) ) && - (This->pConnectSpecific(iface, pReceivePin, pmtCandidate) == S_OK)) - { - hr = S_OK; - TRACE("o_o\n"); - DeleteMediaType(pmtCandidate); - break; - } - DeleteMediaType(pmtCandidate); - } - IEnumMediaTypes_Release(pEnumCandidates); - } - - /* then try receiver filter's media types */ - if (hr != S_OK && SUCCEEDED(hr = IPin_EnumMediaTypes(pReceivePin, &pEnumCandidates))) /* if we haven't already connected successfully */ - { - hr = VFW_E_NO_ACCEPTABLE_TYPES; /* Assume the worst, but set to S_OK if connected successfully */ - - while (S_OK == IEnumMediaTypes_Next(pEnumCandidates, 1, &pmtCandidate, NULL)) - { - if (( !pmt || CompareMediaTypes(pmt, pmtCandidate, TRUE) ) && - (This->pConnectSpecific(iface, pReceivePin, pmtCandidate) == S_OK)) - { - hr = S_OK; - DeleteMediaType(pmtCandidate); - break; - } - DeleteMediaType(pmtCandidate); - } /* while */ - IEnumMediaTypes_Release(pEnumCandidates); - } /* if not found */ - } /* if negotiate media type */ - } /* if succeeded */ - LeaveCriticalSection(This->pin.pCritSec); - - TRACE(" -- %x\n", hr); - return hr; -} - -HRESULT WINAPI OutputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt) -{ - ERR("Incoming connection on an output pin! (%p, %p)\n", pReceivePin, pmt); - - return E_UNEXPECTED; -} - -HRESULT WINAPI OutputPin_Disconnect(IPin * iface) -{ - HRESULT hr; - OutputPin *This = (OutputPin *)iface; - - TRACE("()\n"); - - EnterCriticalSection(This->pin.pCritSec); - { - if (This->pMemInputPin) - { - IMemInputPin_Release(This->pMemInputPin); - This->pMemInputPin = NULL; - } - if (This->pin.pConnectedTo) - { - IPin_Release(This->pin.pConnectedTo); - This->pin.pConnectedTo = NULL; - hr = S_OK; - } - else - hr = S_FALSE; - } - LeaveCriticalSection(This->pin.pCritSec); - - return hr; -} - -HRESULT OutputPin_GetDeliveryBuffer(OutputPin * This, IMediaSample ** ppSample, REFERENCE_TIME * tStart, REFERENCE_TIME * tStop, DWORD dwFlags) -{ - HRESULT hr; - - TRACE("(%p, %p, %p, %x)\n", ppSample, tStart, tStop, dwFlags); - - EnterCriticalSection(This->pin.pCritSec); - { - if (!This->pin.pConnectedTo) - hr = VFW_E_NOT_CONNECTED; - else - { - IMemAllocator * pAlloc = NULL; - - hr = IMemInputPin_GetAllocator(This->pMemInputPin, &pAlloc); - - if (SUCCEEDED(hr)) - hr = IMemAllocator_GetBuffer(pAlloc, ppSample, tStart, tStop, dwFlags); - - if (SUCCEEDED(hr)) - hr = IMediaSample_SetTime(*ppSample, tStart, tStop); - - if (pAlloc) - IMemAllocator_Release(pAlloc); - } - } - LeaveCriticalSection(This->pin.pCritSec); - - return hr; -} - -HRESULT OutputPin_SendSample(OutputPin * This, IMediaSample * pSample) -{ - HRESULT hr = S_OK; - IMemInputPin * pMemConnected = NULL; - - EnterCriticalSection(This->pin.pCritSec); - { - if (!This->pin.pConnectedTo || !This->pMemInputPin) - hr = VFW_E_NOT_CONNECTED; - else - { - /* we don't have the lock held when using This->pMemInputPin, - * so we need to AddRef it to stop it being deleted while we are - * using it. */ - pMemConnected = This->pMemInputPin; - IMemInputPin_AddRef(pMemConnected); - } - } - LeaveCriticalSection(This->pin.pCritSec); - - if (SUCCEEDED(hr)) - { - /* NOTE: if we are in a critical section when Receive is called - * then it causes some problems (most notably with the native Video - * Renderer) if we are re-entered for whatever reason */ - hr = IMemInputPin_Receive(pMemConnected, pSample); - IMemInputPin_Release(pMemConnected); - } - - return hr; -} diff --git a/dlls/qcap/pin.h b/dlls/qcap/pin.h deleted file mode 100644 index 316d3d6..0000000 --- a/dlls/qcap/pin.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * IPin function declarations to allow inheritance - * - * Copyright 2003 Robert Shearman - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -/* This function will process incoming samples to the pin. - * Any return value valid in IMemInputPin::Receive is allowed here - */ -typedef HRESULT (* SAMPLEPROC)(LPVOID userdata, IMediaSample * pSample); - -/* This function will determine whether a type is supported or not. - * It is allowed to return any error value (within reason), as opposed - * to IPin::QueryAccept which is only allowed to return S_OK or S_FALSE. - */ -typedef HRESULT (* QUERYACCEPTPROC)(LPVOID userdata, const AM_MEDIA_TYPE * pmt); - -/* This function is called prior to finalizing a connection with - * another pin and can be used to get things from the other pin - * like IMemInput interfaces. - */ -typedef HRESULT (* PRECONNECTPROC)(IPin * iface, IPin * pConnectPin); - -typedef struct IPinImpl -{ - const struct IPinVtbl * lpVtbl; - LONG refCount; - LPCRITICAL_SECTION pCritSec; - PIN_INFO pinInfo; - IPin * pConnectedTo; - AM_MEDIA_TYPE mtCurrent; - ENUMMEDIADETAILS enumMediaDetails; - QUERYACCEPTPROC fnQueryAccept; - LPVOID pUserData; -} IPinImpl; - -typedef struct OutputPin -{ - /* inheritance C style! */ - IPinImpl pin; - - IMemInputPin * pMemInputPin; - HRESULT (* pConnectSpecific)(IPin * iface, IPin * pReceiver, const AM_MEDIA_TYPE * pmt); - ALLOCATOR_PROPERTIES allocProps; -} OutputPin; - -/*** Initializers ***/ -HRESULT OutputPin_Init(const PIN_INFO * pPinInfo, const ALLOCATOR_PROPERTIES *props, - LPVOID pUserData, QUERYACCEPTPROC pQueryAccept, - LPCRITICAL_SECTION pCritSec, OutputPin * pPinImpl); - -/* Common */ -HRESULT WINAPI IPinImpl_ConnectedTo(IPin * iface, IPin ** ppPin); -HRESULT WINAPI IPinImpl_ConnectionMediaType(IPin * iface, AM_MEDIA_TYPE * pmt); -HRESULT WINAPI IPinImpl_QueryPinInfo(IPin * iface, PIN_INFO * pInfo); -HRESULT WINAPI IPinImpl_QueryDirection(IPin * iface, PIN_DIRECTION * pPinDir); -HRESULT WINAPI IPinImpl_QueryId(IPin * iface, LPWSTR * Id); -HRESULT WINAPI IPinImpl_QueryAccept(IPin * iface, const AM_MEDIA_TYPE * pmt); -HRESULT WINAPI IPinImpl_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum); -HRESULT WINAPI IPinImpl_QueryInternalConnections(IPin * iface, IPin ** apPin, ULONG * cPin); - -/* Output Pin */ -HRESULT WINAPI OutputPin_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt); -HRESULT WINAPI OutputPin_Disconnect(IPin * iface); -HRESULT WINAPI OutputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt); - -HRESULT OutputPin_GetDeliveryBuffer(OutputPin * This, IMediaSample ** ppSample, REFERENCE_TIME * tStart, REFERENCE_TIME * tStop, DWORD dwFlags); -HRESULT OutputPin_SendSample(OutputPin * This, IMediaSample * pSample); diff --git a/dlls/qcap/qcap_main.h b/dlls/qcap/qcap_main.h index a840655..9dfa509 100644 --- a/dlls/qcap/qcap_main.h +++ b/dlls/qcap/qcap_main.h @@ -20,6 +20,9 @@ #ifndef _QCAP_MAIN_H_DEFINED #define _QCAP_MAIN_H_DEFINED +#include "wine/list.h" +#include "strmbase/strmbase.h" + extern DWORD ObjectRefCount(BOOL increment); extern IUnknown * WINAPI QCAP_createAudioCaptureFilter(IUnknown *pUnkOuter, HRESULT *phr); @@ -35,27 +38,6 @@ extern IUnknown * WINAPI QCAP_createInfinitePinTeeFilter(IUnknown *pUnkOuter, HR extern IUnknown * WINAPI QCAP_createSmartTeeFilter(IUnknown *pUnkOuter, HRESULT *phr); extern IUnknown * WINAPI QCAP_createAudioInputMixerPropertyPage(IUnknown *pUnkOuter, HRESULT *phr); -typedef struct tagENUMPINDETAILS -{ - ULONG cPins; - IPin ** ppPins; -} ENUMPINDETAILS; - -typedef struct tagENUMEDIADETAILS -{ - ULONG cMediaTypes; - AM_MEDIA_TYPE * pMediaTypes; -} ENUMMEDIADETAILS; - -HRESULT IEnumPinsImpl_Construct(const ENUMPINDETAILS * pDetails, IEnumPins ** ppEnum); -HRESULT IEnumMediaTypesImpl_Construct(const ENUMMEDIADETAILS * pDetails, IEnumMediaTypes ** ppEnum); - -HRESULT CopyMediaType(AM_MEDIA_TYPE * pDest, const AM_MEDIA_TYPE *pSrc); -void FreeMediaType(AM_MEDIA_TYPE * pmt); -void DeleteMediaType(AM_MEDIA_TYPE * pmt); -BOOL CompareMediaTypes(const AM_MEDIA_TYPE * pmt1, const AM_MEDIA_TYPE * pmt2, BOOL bWildcards); -void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE * pmt); - enum YUV_Format { /* Last 2 numbers give the skip info, the smaller they are the better * Planar: diff --git a/dlls/qcap/v4l.c b/dlls/qcap/v4l.c index d4f9417..ee7ad31 100644 --- a/dlls/qcap/v4l.c +++ b/dlls/qcap/v4l.c @@ -42,7 +42,6 @@ #include "capture.h" #include "qcap_main.h" -#include "pin.h" #include #include diff --git a/dlls/qcap/vfwcapture.c b/dlls/qcap/vfwcapture.c index fa4754f..ea5d570 100644 --- a/dlls/qcap/vfwcapture.c +++ b/dlls/qcap/vfwcapture.c @@ -35,7 +35,6 @@ #include "qcap_main.h" #include "wine/debug.h" -#include "pin.h" #include "capture.h" #include "uuids.h" #include "vfwmsgs.h" @@ -281,18 +280,28 @@ VfwCapture_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock) } /** IBaseFilter methods **/ +static HRESULT VfwCapture_GetPin(IBaseFilter *iface, ULONG pos, IPin **pin, DWORD *lastsynctick) +{ + VfwCapture *This = (VfwCapture *)iface; + + *lastsynctick = 0; + + TRACE("Asking for pos %x\n", pos); + + if (pos > 0) + return S_FALSE; + + *pin = This->pOutputPin; + IPin_AddRef(*pin); + return S_OK; +} static HRESULT WINAPI VfwCapture_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum) { - ENUMPINDETAILS epd; - VfwCapture *This = (VfwCapture *)iface; - TRACE("(%p)\n", ppEnum); - epd.cPins = 1; - epd.ppPins = &This->pOutputPin; - return IEnumPinsImpl_Construct(&epd, ppEnum); + return IEnumPinsImpl_Construct(ppEnum, VfwCapture_GetPin, iface); } static HRESULT WINAPI VfwCapture_FindPin(IBaseFilter * iface, LPCWSTR Id, IPin **ppPin) @@ -745,10 +754,6 @@ VfwPin_Construct( IBaseFilter * pBaseFilter, LPCRITICAL_SECTION pCritSec, PIN_INFO piOutput; HRESULT hr; - pPinImpl = CoTaskMemAlloc( sizeof(*pPinImpl) ); - if (!pPinImpl) - return E_OUTOFMEMORY; - /* What we put here doesn't matter, the driver function should override it then commit */ ap.cBuffers = 3; @@ -761,7 +766,7 @@ VfwPin_Construct( IBaseFilter * pBaseFilter, LPCRITICAL_SECTION pCritSec, lstrcpyW(piOutput.achName, wszOutputPinName); ObjectRefCount(TRUE); - hr = OutputPin_Init(&piOutput, &ap, pBaseFilter, NULL, pCritSec, &pPinImpl->pin); + hr = OutputPin_Construct(NULL, sizeof(*pPinImpl), &piOutput, &ap, pBaseFilter, NULL, pCritSec, (IPin **)&pPinImpl); if (SUCCEEDED(hr)) { pPinImpl->KSP_VT = &KSP_VTable; -- 1.5.4.1