10d946034ba89d5f995807e2618bc50f2468711f
[reactos.git] / reactos / lib / 3rdparty / strmbase / filter.c
1 /*
2 * Generic Implementation of IBaseFilter Interface
3 *
4 * Copyright 2010 Aric Stewart, CodeWeavers
5 *
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.
10 *
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.
15 *
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
19 */
20
21 #include "strmbase_private.h"
22
23 static inline BaseFilter *impl_from_IBaseFilter(IBaseFilter *iface)
24 {
25 return CONTAINING_RECORD(iface, BaseFilter, IBaseFilter_iface);
26 }
27
28 HRESULT WINAPI BaseFilterImpl_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv)
29 {
30 TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv);
31
32 *ppv = NULL;
33
34 if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPersist) ||
35 IsEqualIID(riid, &IID_IMediaFilter) || IsEqualIID(riid, &IID_IBaseFilter))
36 {
37 *ppv = iface;
38 IBaseFilter_AddRef(iface);
39 return S_OK;
40 }
41
42 return E_NOINTERFACE;
43 }
44
45 ULONG WINAPI BaseFilterImpl_AddRef(IBaseFilter * iface)
46 {
47 BaseFilter *This = impl_from_IBaseFilter(iface);
48 ULONG refCount = InterlockedIncrement(&This->refCount);
49
50 TRACE("(%p)->() AddRef from %d\n", This, refCount - 1);
51
52 return refCount;
53 }
54
55 ULONG WINAPI BaseFilterImpl_Release(IBaseFilter * iface)
56 {
57 BaseFilter *This = impl_from_IBaseFilter(iface);
58 ULONG refCount = InterlockedDecrement(&This->refCount);
59
60 TRACE("(%p)->() Release from %d\n", This, refCount + 1);
61
62 if (!refCount)
63 {
64 if (This->pClock)
65 IReferenceClock_Release(This->pClock);
66
67 This->IBaseFilter_iface.lpVtbl = NULL;
68 This->csFilter.DebugInfo->Spare[0] = 0;
69 DeleteCriticalSection(&This->csFilter);
70 }
71
72 return refCount;
73 }
74
75 HRESULT WINAPI BaseFilterImpl_GetClassID(IBaseFilter * iface, CLSID * pClsid)
76 {
77 BaseFilter *This = impl_from_IBaseFilter(iface);
78 TRACE("(%p)->(%p)\n", This, pClsid);
79
80 *pClsid = This->clsid;
81
82 return S_OK;
83 }
84
85 HRESULT WINAPI BaseFilterImpl_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState )
86 {
87 BaseFilter *This = impl_from_IBaseFilter(iface);
88 TRACE("(%p)->(%d, %p)\n", This, dwMilliSecsTimeout, pState);
89
90 EnterCriticalSection(&This->csFilter);
91 {
92 *pState = This->state;
93 }
94 LeaveCriticalSection(&This->csFilter);
95
96 return S_OK;
97 }
98
99 HRESULT WINAPI BaseFilterImpl_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock)
100 {
101 BaseFilter *This = impl_from_IBaseFilter(iface);
102 TRACE("(%p)->(%p)\n", This, pClock);
103
104 EnterCriticalSection(&This->csFilter);
105 {
106 if (This->pClock)
107 IReferenceClock_Release(This->pClock);
108 This->pClock = pClock;
109 if (This->pClock)
110 IReferenceClock_AddRef(This->pClock);
111 }
112 LeaveCriticalSection(&This->csFilter);
113
114 return S_OK;
115 }
116
117 HRESULT WINAPI BaseFilterImpl_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock)
118 {
119 BaseFilter *This = impl_from_IBaseFilter(iface);
120 TRACE("(%p)->(%p)\n", This, ppClock);
121
122 EnterCriticalSection(&This->csFilter);
123 {
124 *ppClock = This->pClock;
125 if (This->pClock)
126 IReferenceClock_AddRef(This->pClock);
127 }
128 LeaveCriticalSection(&This->csFilter);
129
130 return S_OK;
131 }
132
133 HRESULT WINAPI BaseFilterImpl_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum)
134 {
135 BaseFilter *This = impl_from_IBaseFilter(iface);
136
137 TRACE("(%p)->(%p)\n", iface, ppEnum);
138
139 return EnumPins_Construct(This, This->pFuncsTable->pfnGetPin, This->pFuncsTable->pfnGetPinCount, BaseFilterImpl_GetPinVersion, ppEnum);
140 }
141
142
143 HRESULT WINAPI BaseFilterImpl_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo)
144 {
145 BaseFilter *This = impl_from_IBaseFilter(iface);
146 TRACE("(%p)->(%p)\n", This, pInfo);
147
148 strcpyW(pInfo->achName, This->filterInfo.achName);
149 pInfo->pGraph = This->filterInfo.pGraph;
150
151 if (pInfo->pGraph)
152 IFilterGraph_AddRef(pInfo->pGraph);
153
154 return S_OK;
155 }
156
157 HRESULT WINAPI BaseFilterImpl_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName )
158 {
159 HRESULT hr = S_OK;
160 BaseFilter *This = impl_from_IBaseFilter(iface);
161
162 TRACE("(%p)->(%p, %s)\n", This, pGraph, debugstr_w(pName));
163
164 EnterCriticalSection(&This->csFilter);
165 {
166 if (pName)
167 strcpyW(This->filterInfo.achName, pName);
168 else
169 *This->filterInfo.achName = '\0';
170 This->filterInfo.pGraph = pGraph; /* NOTE: do NOT increase ref. count */
171 }
172 LeaveCriticalSection(&This->csFilter);
173
174 return hr;
175 }
176
177 HRESULT WINAPI BaseFilterImpl_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo)
178 {
179 TRACE("(%p)->(%p)\n", iface, pVendorInfo);
180 return E_NOTIMPL;
181 }
182
183 LONG WINAPI BaseFilterImpl_GetPinVersion(BaseFilter * This)
184 {
185 TRACE("(%p)\n", This);
186 return This->pinVersion;
187 }
188
189 VOID WINAPI BaseFilterImpl_IncrementPinVersion(BaseFilter * This)
190 {
191 InterlockedIncrement(&This->pinVersion);
192 TRACE("(%p) -> New pinVersion %i\n", This,This->pinVersion);
193 }
194
195 HRESULT WINAPI BaseFilter_Init(BaseFilter * This, const IBaseFilterVtbl *Vtbl, const CLSID *pClsid, DWORD_PTR DebugInfo, const BaseFilterFuncTable* pBaseFuncsTable)
196 {
197 This->IBaseFilter_iface.lpVtbl = Vtbl;
198 This->refCount = 1;
199 InitializeCriticalSection(&This->csFilter);
200 This->state = State_Stopped;
201 This->rtStreamStart = 0;
202 This->pClock = NULL;
203 ZeroMemory(&This->filterInfo, sizeof(FILTER_INFO));
204 This->clsid = *pClsid;
205 This->csFilter.DebugInfo->Spare[0] = DebugInfo;
206 This->pinVersion = 1;
207
208 This->pFuncsTable = pBaseFuncsTable;
209
210 return S_OK;
211 }