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