d3drm: Move mesh loading code into a separate function so it can be shared.
[wine] / dlls / amstream / mediastreamfilter.c
1 /*
2  * Implementation of MediaStream Filter
3  *
4  * Copyright 2008 Christian Costa
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 "wine/debug.h"
22
23 #define COBJMACROS
24
25 #include "winbase.h"
26 #include "wingdi.h"
27 #include "dshow.h"
28
29 #include "wine/strmbase.h"
30
31 #include "amstream_private.h"
32 #include "amstream.h"
33
34 #include "ddstream.h"
35
36 WINE_DEFAULT_DEBUG_CHANNEL(amstream);
37
38 typedef struct {
39     BaseFilter filter;
40     ULONG nb_streams;
41     IMediaStream** streams;
42 } IMediaStreamFilterImpl;
43
44 static inline IMediaStreamFilterImpl *impl_from_IMediaStreamFilter(IMediaStreamFilter *iface)
45 {
46     return CONTAINING_RECORD(iface, IMediaStreamFilterImpl, filter);
47 }
48
49 /*** IUnknown methods ***/
50
51 static HRESULT WINAPI MediaStreamFilterImpl_QueryInterface(IMediaStreamFilter *iface, REFIID riid,
52         void **ppv)
53 {
54     IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface);
55
56     TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv);
57
58     *ppv = NULL;
59
60     if (IsEqualIID(riid, &IID_IUnknown))
61         *ppv = This;
62     else if (IsEqualIID(riid, &IID_IPersist))
63         *ppv = This;
64     else if (IsEqualIID(riid, &IID_IMediaFilter))
65         *ppv = This;
66     else if (IsEqualIID(riid, &IID_IBaseFilter))
67         *ppv = This;
68     else if (IsEqualIID(riid, &IID_IMediaStreamFilter))
69         *ppv = This;
70
71     if (*ppv)
72     {
73         IUnknown_AddRef((IUnknown *)(*ppv));
74         return S_OK;
75     }
76
77     return E_NOINTERFACE;
78 }
79
80 static ULONG WINAPI MediaStreamFilterImpl_AddRef(IMediaStreamFilter *iface)
81 {
82     return BaseFilterImpl_AddRef((IBaseFilter*)iface);
83 }
84
85 static ULONG WINAPI MediaStreamFilterImpl_Release(IMediaStreamFilter *iface)
86 {
87     IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface);
88     ULONG refCount = BaseFilterImpl_Release((IBaseFilter*)iface);
89
90     TRACE("(%p)->() Release from %d\n", iface, refCount + 1);
91
92     if (!refCount)
93     {
94         int i;
95         for (i = 0; i < This->nb_streams; i++)
96             IMediaStream_Release(This->streams[i]);
97         HeapFree(GetProcessHeap(), 0, This);
98     }
99
100     return refCount;
101 }
102
103 /*** IPersist methods ***/
104
105 static HRESULT WINAPI MediaStreamFilterImpl_GetClassID(IMediaStreamFilter * iface, CLSID * pClsid)
106 {
107     return BaseFilterImpl_GetClassID((IBaseFilter*)iface, pClsid);
108 }
109
110 /*** IBaseFilter methods ***/
111
112 static HRESULT WINAPI MediaStreamFilterImpl_Stop(IMediaStreamFilter * iface)
113 {
114     FIXME("(%p)->(): Stub!\n", iface);
115
116     return E_NOTIMPL;
117 }
118
119 static HRESULT WINAPI MediaStreamFilterImpl_Pause(IMediaStreamFilter * iface)
120 {
121     FIXME("(%p)->(): Stub!\n", iface);
122
123     return E_NOTIMPL;
124 }
125
126 static HRESULT WINAPI MediaStreamFilterImpl_Run(IMediaStreamFilter * iface, REFERENCE_TIME tStart)
127 {
128     FIXME("(%p)->(%s): Stub!\n", iface, wine_dbgstr_longlong(tStart));
129
130     return E_NOTIMPL;
131 }
132
133 static HRESULT WINAPI MediaStreamFilterImpl_GetState(IMediaStreamFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
134 {
135     return BaseFilterImpl_GetState((IBaseFilter*)iface, dwMilliSecsTimeout, pState);
136 }
137
138 static HRESULT WINAPI MediaStreamFilterImpl_SetSyncSource(IMediaStreamFilter * iface, IReferenceClock *pClock)
139 {
140     return BaseFilterImpl_SetSyncSource((IBaseFilter*)iface, pClock);
141 }
142
143 static HRESULT WINAPI MediaStreamFilterImpl_GetSyncSource(IMediaStreamFilter * iface, IReferenceClock **ppClock)
144 {
145     return BaseFilterImpl_GetSyncSource((IBaseFilter*)iface, ppClock);
146 }
147
148 static HRESULT WINAPI MediaStreamFilterImpl_EnumPins(IMediaStreamFilter * iface, IEnumPins **ppEnum)
149 {
150     return BaseFilterImpl_EnumPins((IBaseFilter*)iface, ppEnum);
151 }
152
153 static HRESULT WINAPI MediaStreamFilterImpl_FindPin(IMediaStreamFilter * iface, LPCWSTR Id, IPin **ppPin)
154 {
155     FIXME("(%p)->(%s,%p): Stub!\n", iface, debugstr_w(Id), ppPin);
156
157     return E_NOTIMPL;
158 }
159
160 static HRESULT WINAPI MediaStreamFilterImpl_QueryFilterInfo(IMediaStreamFilter * iface, FILTER_INFO *pInfo)
161 {
162     return BaseFilterImpl_QueryFilterInfo((IBaseFilter*)iface, pInfo);
163 }
164
165 static HRESULT WINAPI MediaStreamFilterImpl_JoinFilterGraph(IMediaStreamFilter * iface, IFilterGraph *pGraph, LPCWSTR pName)
166 {
167     return BaseFilterImpl_JoinFilterGraph((IBaseFilter*)iface, pGraph, pName);
168 }
169
170 static HRESULT WINAPI MediaStreamFilterImpl_QueryVendorInfo(IMediaStreamFilter * iface, LPWSTR *pVendorInfo)
171 {
172     return BaseFilterImpl_QueryVendorInfo((IBaseFilter*)iface, pVendorInfo);
173 }
174
175 /*** IMediaStreamFilter methods ***/
176
177 static HRESULT WINAPI MediaStreamFilterImpl_AddMediaStream(IMediaStreamFilter* iface, IAMMediaStream *pAMMediaStream)
178 {
179     IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface);
180     IMediaStream** streams;
181
182     TRACE("(%p)->(%p)\n", iface, pAMMediaStream);
183
184     streams = CoTaskMemRealloc(This->streams, (This->nb_streams + 1) * sizeof(IMediaStream*));
185     if (!streams)
186         return E_OUTOFMEMORY;
187     This->streams = streams;
188     This->streams[This->nb_streams] = (IMediaStream*)pAMMediaStream;
189     This->nb_streams++;
190
191     IMediaStream_AddRef((IMediaStream*)pAMMediaStream);
192
193     return S_OK;
194 }
195
196 static HRESULT WINAPI MediaStreamFilterImpl_GetMediaStream(IMediaStreamFilter* iface, REFMSPID idPurpose, IMediaStream **ppMediaStream)
197 {
198     IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface);
199     MSPID purpose_id;
200     unsigned int i;
201
202     TRACE("(%p)->(%s,%p)\n", iface, debugstr_guid(idPurpose), ppMediaStream);
203
204     for (i = 0; i < This->nb_streams; i++)
205     {
206         IMediaStream_GetInformation(This->streams[i], &purpose_id, NULL);
207         if (IsEqualIID(&purpose_id, idPurpose))
208         {
209             *ppMediaStream = This->streams[i];
210             IMediaStream_AddRef(*ppMediaStream);
211             return S_OK;
212         }
213     }
214
215     return MS_E_NOSTREAM;
216 }
217
218 static HRESULT WINAPI MediaStreamFilterImpl_EnumMediaStreams(IMediaStreamFilter* iface, LONG Index, IMediaStream **ppMediaStream)
219 {
220     FIXME("(%p)->(%d,%p): Stub!\n", iface, Index, ppMediaStream);
221
222     return E_NOTIMPL;
223 }
224
225 static HRESULT WINAPI MediaStreamFilterImpl_SupportSeeking(IMediaStreamFilter* iface, BOOL bRenderer)
226 {
227     FIXME("(%p)->(%d): Stub!\n", iface, bRenderer);
228
229     return E_NOTIMPL;
230 }
231
232 static HRESULT WINAPI MediaStreamFilterImpl_ReferenceTimeToStreamTime(IMediaStreamFilter* iface, REFERENCE_TIME *pTime)
233 {
234     FIXME("(%p)->(%p): Stub!\n", iface, pTime);
235
236     return E_NOTIMPL;
237 }
238
239 static HRESULT WINAPI MediaStreamFilterImpl_GetCurrentStreamTime(IMediaStreamFilter* iface, REFERENCE_TIME *pCurrentStreamTime)
240 {
241     FIXME("(%p)->(%p): Stub!\n", iface, pCurrentStreamTime);
242
243     return E_NOTIMPL;
244 }
245
246 static HRESULT WINAPI MediaStreamFilterImpl_WaitUntil(IMediaStreamFilter* iface, REFERENCE_TIME WaitStreamTime)
247 {
248     FIXME("(%p)->(%s): Stub!\n", iface, wine_dbgstr_longlong(WaitStreamTime));
249
250     return E_NOTIMPL;
251 }
252
253 static HRESULT WINAPI MediaStreamFilterImpl_Flush(IMediaStreamFilter* iface, BOOL bCancelEOS)
254 {
255     FIXME("(%p)->(%d): Stub!\n", iface, bCancelEOS);
256
257     return E_NOTIMPL;
258 }
259
260 static HRESULT WINAPI MediaStreamFilterImpl_EndOfStream(IMediaStreamFilter* iface)
261 {
262     FIXME("(%p)->(): Stub!\n",  iface);
263
264     return E_NOTIMPL;
265 }
266
267 static const IMediaStreamFilterVtbl MediaStreamFilter_Vtbl =
268 {
269     MediaStreamFilterImpl_QueryInterface,
270     MediaStreamFilterImpl_AddRef,
271     MediaStreamFilterImpl_Release,
272     MediaStreamFilterImpl_GetClassID,
273     MediaStreamFilterImpl_Stop,
274     MediaStreamFilterImpl_Pause,
275     MediaStreamFilterImpl_Run,
276     MediaStreamFilterImpl_GetState,
277     MediaStreamFilterImpl_SetSyncSource,
278     MediaStreamFilterImpl_GetSyncSource,
279     MediaStreamFilterImpl_EnumPins,
280     MediaStreamFilterImpl_FindPin,
281     MediaStreamFilterImpl_QueryFilterInfo,
282     MediaStreamFilterImpl_JoinFilterGraph,
283     MediaStreamFilterImpl_QueryVendorInfo,
284     MediaStreamFilterImpl_AddMediaStream,
285     MediaStreamFilterImpl_GetMediaStream,
286     MediaStreamFilterImpl_EnumMediaStreams,
287     MediaStreamFilterImpl_SupportSeeking,
288     MediaStreamFilterImpl_ReferenceTimeToStreamTime,
289     MediaStreamFilterImpl_GetCurrentStreamTime,
290     MediaStreamFilterImpl_WaitUntil,
291     MediaStreamFilterImpl_Flush,
292     MediaStreamFilterImpl_EndOfStream
293 };
294
295 static IPin* WINAPI MediaStreamFilterImpl_GetPin(BaseFilter *iface, int pos)
296 {
297     /* No pins */
298     return NULL;
299 }
300
301 static LONG WINAPI MediaStreamFilterImpl_GetPinCount(BaseFilter *iface)
302 {
303     /* No pins */
304     return 0;
305 }
306
307 static const BaseFilterFuncTable BaseFuncTable = {
308     MediaStreamFilterImpl_GetPin,
309     MediaStreamFilterImpl_GetPinCount
310 };
311
312 HRESULT MediaStreamFilter_create(IUnknown *pUnkOuter, void **ppObj)
313 {
314     IMediaStreamFilterImpl* object;
315
316     TRACE("(%p,%p)\n", pUnkOuter, ppObj);
317
318     if( pUnkOuter )
319         return CLASS_E_NOAGGREGATION;
320
321     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IMediaStreamFilterImpl));
322     if (!object)
323     {
324         ERR("Out of memory\n");
325         return E_OUTOFMEMORY;
326     }
327
328     BaseFilter_Init(&object->filter, (IBaseFilterVtbl*)&MediaStreamFilter_Vtbl, &CLSID_MediaStreamFilter, (DWORD_PTR)(__FILE__ ": MediaStreamFilterImpl.csFilter"), &BaseFuncTable);
329
330     *ppObj = object;
331
332     return S_OK;
333 }