2 * Generic Implementation of IBaseFilter Interface
4 * Copyright 2010 Aric Stewart, CodeWeavers
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
24 #include "wine/debug.h"
25 #include "wine/unicode.h"
26 #include "wine/strmbase.h"
30 WINE_DEFAULT_DEBUG_CHANNEL(strmbase
);
32 static inline BaseFilter
*impl_from_IBaseFilter(IBaseFilter
*iface
)
34 return CONTAINING_RECORD(iface
, BaseFilter
, IBaseFilter_iface
);
37 HRESULT WINAPI
BaseFilterImpl_QueryInterface(IBaseFilter
* iface
, REFIID riid
, LPVOID
* ppv
)
39 TRACE("(%p)->(%s, %p)\n", iface
, debugstr_guid(riid
), ppv
);
43 if (IsEqualIID(riid
, &IID_IUnknown
) || IsEqualIID(riid
, &IID_IPersist
) ||
44 IsEqualIID(riid
, &IID_IMediaFilter
) || IsEqualIID(riid
, &IID_IBaseFilter
))
47 IBaseFilter_AddRef(iface
);
54 ULONG WINAPI
BaseFilterImpl_AddRef(IBaseFilter
* iface
)
56 BaseFilter
*This
= impl_from_IBaseFilter(iface
);
57 ULONG refCount
= InterlockedIncrement(&This
->refCount
);
59 TRACE("(%p)->() AddRef from %d\n", This
, refCount
- 1);
64 ULONG WINAPI
BaseFilterImpl_Release(IBaseFilter
* iface
)
66 BaseFilter
*This
= impl_from_IBaseFilter(iface
);
67 ULONG refCount
= InterlockedDecrement(&This
->refCount
);
69 TRACE("(%p)->() Release from %d\n", This
, refCount
+ 1);
72 BaseFilter_Destroy(This
);
77 HRESULT WINAPI
BaseFilterImpl_GetClassID(IBaseFilter
* iface
, CLSID
* pClsid
)
79 BaseFilter
*This
= impl_from_IBaseFilter(iface
);
80 TRACE("(%p)->(%p)\n", This
, pClsid
);
82 *pClsid
= This
->clsid
;
87 HRESULT WINAPI
BaseFilterImpl_GetState(IBaseFilter
* iface
, DWORD dwMilliSecsTimeout
, FILTER_STATE
*pState
)
89 BaseFilter
*This
= impl_from_IBaseFilter(iface
);
90 TRACE("(%p)->(%d, %p)\n", This
, dwMilliSecsTimeout
, pState
);
92 EnterCriticalSection(&This
->csFilter
);
94 *pState
= This
->state
;
96 LeaveCriticalSection(&This
->csFilter
);
101 HRESULT WINAPI
BaseFilterImpl_SetSyncSource(IBaseFilter
* iface
, IReferenceClock
*pClock
)
103 BaseFilter
*This
= impl_from_IBaseFilter(iface
);
104 TRACE("(%p)->(%p)\n", This
, pClock
);
106 EnterCriticalSection(&This
->csFilter
);
109 IReferenceClock_Release(This
->pClock
);
110 This
->pClock
= pClock
;
112 IReferenceClock_AddRef(This
->pClock
);
114 LeaveCriticalSection(&This
->csFilter
);
119 HRESULT WINAPI
BaseFilterImpl_GetSyncSource(IBaseFilter
* iface
, IReferenceClock
**ppClock
)
121 BaseFilter
*This
= impl_from_IBaseFilter(iface
);
122 TRACE("(%p)->(%p)\n", This
, ppClock
);
124 EnterCriticalSection(&This
->csFilter
);
126 *ppClock
= This
->pClock
;
128 IReferenceClock_AddRef(This
->pClock
);
130 LeaveCriticalSection(&This
->csFilter
);
135 HRESULT WINAPI
BaseFilterImpl_EnumPins(IBaseFilter
* iface
, IEnumPins
**ppEnum
)
137 BaseFilter
*This
= impl_from_IBaseFilter(iface
);
139 TRACE("(%p)->(%p)\n", iface
, ppEnum
);
141 return EnumPins_Construct(This
, This
->pFuncsTable
->pfnGetPin
, This
->pFuncsTable
->pfnGetPinCount
, BaseFilterImpl_GetPinVersion
, ppEnum
);
144 HRESULT WINAPI
BaseFilterImpl_FindPin(IBaseFilter
*iface
, const WCHAR
*id
, IPin
**ret
)
146 BaseFilter
*This
= impl_from_IBaseFilter(iface
);
152 TRACE("(%p)->(%s, %p)\n", This
, debugstr_w(id
), ret
);
154 for (i
= 0; i
< This
->pFuncsTable
->pfnGetPinCount(This
); ++i
)
156 pin
= This
->pFuncsTable
->pfnGetPin(This
, i
);
157 hr
= IPin_QueryPinInfo(pin
, &info
);
163 if (info
.pFilter
) IBaseFilter_Release(info
.pFilter
);
165 if (!strcmpW(id
, info
.achName
))
174 return VFW_E_NOT_FOUND
;
177 HRESULT WINAPI
BaseFilterImpl_QueryFilterInfo(IBaseFilter
* iface
, FILTER_INFO
*pInfo
)
179 BaseFilter
*This
= impl_from_IBaseFilter(iface
);
180 TRACE("(%p)->(%p)\n", This
, pInfo
);
182 strcpyW(pInfo
->achName
, This
->filterInfo
.achName
);
183 pInfo
->pGraph
= This
->filterInfo
.pGraph
;
186 IFilterGraph_AddRef(pInfo
->pGraph
);
191 HRESULT WINAPI
BaseFilterImpl_JoinFilterGraph(IBaseFilter
* iface
, IFilterGraph
*pGraph
, LPCWSTR pName
)
193 BaseFilter
*This
= impl_from_IBaseFilter(iface
);
195 TRACE("(%p)->(%p, %s)\n", This
, pGraph
, debugstr_w(pName
));
197 EnterCriticalSection(&This
->csFilter
);
200 strcpyW(This
->filterInfo
.achName
, pName
);
202 *This
->filterInfo
.achName
= '\0';
203 This
->filterInfo
.pGraph
= pGraph
; /* NOTE: do NOT increase ref. count */
205 LeaveCriticalSection(&This
->csFilter
);
210 HRESULT WINAPI
BaseFilterImpl_QueryVendorInfo(IBaseFilter
* iface
, LPWSTR
*pVendorInfo
)
212 TRACE("(%p)->(%p)\n", iface
, pVendorInfo
);
216 LONG WINAPI
BaseFilterImpl_GetPinVersion(BaseFilter
* This
)
218 TRACE("(%p)\n", This
);
219 return This
->pinVersion
;
222 VOID WINAPI
BaseFilterImpl_IncrementPinVersion(BaseFilter
* This
)
224 InterlockedIncrement(&This
->pinVersion
);
225 TRACE("(%p) -> New pinVersion %i\n", This
,This
->pinVersion
);
228 HRESULT WINAPI
BaseFilter_Init(BaseFilter
* This
, const IBaseFilterVtbl
*Vtbl
, const CLSID
*pClsid
, DWORD_PTR DebugInfo
, const BaseFilterFuncTable
* pBaseFuncsTable
)
230 This
->IBaseFilter_iface
.lpVtbl
= Vtbl
;
232 InitializeCriticalSection(&This
->csFilter
);
233 This
->state
= State_Stopped
;
234 This
->rtStreamStart
= 0;
236 ZeroMemory(&This
->filterInfo
, sizeof(FILTER_INFO
));
237 This
->clsid
= *pClsid
;
238 This
->csFilter
.DebugInfo
->Spare
[0] = DebugInfo
;
239 This
->pinVersion
= 1;
241 This
->pFuncsTable
= pBaseFuncsTable
;
246 HRESULT WINAPI
BaseFilter_Destroy(BaseFilter
* This
)
249 IReferenceClock_Release(This
->pClock
);
251 This
->IBaseFilter_iface
.lpVtbl
= NULL
;
252 This
->csFilter
.DebugInfo
->Spare
[0] = 0;
253 DeleteCriticalSection(&This
->csFilter
);