Assorted typo, spelling, wording and case fixes.
[wine] / dlls / amstream / mediastreamfilter.c
1 /*
2  * Implementation of MediaStream Filter
3  *
4  * Copyright 2008, 2012 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 MediaStreamFilter_InputPin
39 {
40     BaseInputPin pin;
41 } MediaStreamFilter_InputPin;
42
43 static const IPinVtbl MediaStreamFilter_InputPin_Vtbl =
44 {
45     BaseInputPinImpl_QueryInterface,
46     BasePinImpl_AddRef,
47     BaseInputPinImpl_Release,
48     BaseInputPinImpl_Connect,
49     BaseInputPinImpl_ReceiveConnection,
50     BasePinImpl_Disconnect,
51     BasePinImpl_ConnectedTo,
52     BasePinImpl_ConnectionMediaType,
53     BasePinImpl_QueryPinInfo,
54     BasePinImpl_QueryDirection,
55     BasePinImpl_QueryId,
56     BasePinImpl_QueryAccept,
57     BasePinImpl_EnumMediaTypes,
58     BasePinImpl_QueryInternalConnections,
59     BaseInputPinImpl_EndOfStream,
60     BaseInputPinImpl_BeginFlush,
61     BaseInputPinImpl_EndFlush,
62     BasePinImpl_NewSegment
63 };
64
65 typedef struct {
66     BaseFilter filter;
67     ULONG nb_streams;
68     IMediaStream** streams;
69     IPin** pins;
70 } IMediaStreamFilterImpl;
71
72 static inline IMediaStreamFilterImpl *impl_from_IMediaStreamFilter(IMediaStreamFilter *iface)
73 {
74     return CONTAINING_RECORD(iface, IMediaStreamFilterImpl, filter);
75 }
76
77 static HRESULT WINAPI BasePinImpl_CheckMediaType(BasePin *This, const AM_MEDIA_TYPE *pmt)
78 {
79     return S_FALSE;
80 }
81
82 static LONG WINAPI BasePinImp_GetMediaTypeVersion(BasePin *This)
83 {
84     return 0;
85 }
86
87 static HRESULT WINAPI BasePinImp_GetMediaType(BasePin *This, int iPosition, AM_MEDIA_TYPE *amt)
88 {
89     return S_FALSE;
90 }
91
92 static const  BasePinFuncTable input_BaseFuncTable = {
93     BasePinImpl_CheckMediaType,
94     NULL,
95     BasePinImp_GetMediaTypeVersion,
96     BasePinImp_GetMediaType
97 };
98
99 static const BaseInputPinFuncTable input_BaseInputFuncTable = {
100     NULL
101 };
102
103 /*** IUnknown methods ***/
104
105 static HRESULT WINAPI MediaStreamFilterImpl_QueryInterface(IMediaStreamFilter *iface, REFIID riid,
106         void **ppv)
107 {
108     IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface);
109
110     TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppv);
111
112     *ppv = NULL;
113
114     if (IsEqualIID(riid, &IID_IUnknown))
115         *ppv = This;
116     else if (IsEqualIID(riid, &IID_IPersist))
117         *ppv = This;
118     else if (IsEqualIID(riid, &IID_IMediaFilter))
119         *ppv = This;
120     else if (IsEqualIID(riid, &IID_IBaseFilter))
121         *ppv = This;
122     else if (IsEqualIID(riid, &IID_IMediaStreamFilter))
123         *ppv = This;
124
125     if (*ppv)
126     {
127         IUnknown_AddRef((IUnknown *)(*ppv));
128         return S_OK;
129     }
130
131     return E_NOINTERFACE;
132 }
133
134 static ULONG WINAPI MediaStreamFilterImpl_AddRef(IMediaStreamFilter *iface)
135 {
136     return BaseFilterImpl_AddRef((IBaseFilter*)iface);
137 }
138
139 static ULONG WINAPI MediaStreamFilterImpl_Release(IMediaStreamFilter *iface)
140 {
141     IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface);
142     ULONG refCount = BaseFilterImpl_Release((IBaseFilter*)iface);
143
144     TRACE("(%p)->() Release from %d\n", iface, refCount + 1);
145
146     if (!refCount)
147     {
148         int i;
149         for (i = 0; i < This->nb_streams; i++)
150         {
151             IMediaStream_Release(This->streams[i]);
152             IPin_Release(This->pins[i]);
153         }
154         HeapFree(GetProcessHeap(), 0, This);
155     }
156
157     return refCount;
158 }
159
160 /*** IPersist methods ***/
161
162 static HRESULT WINAPI MediaStreamFilterImpl_GetClassID(IMediaStreamFilter * iface, CLSID * pClsid)
163 {
164     return BaseFilterImpl_GetClassID((IBaseFilter*)iface, pClsid);
165 }
166
167 /*** IBaseFilter methods ***/
168
169 static HRESULT WINAPI MediaStreamFilterImpl_Stop(IMediaStreamFilter * iface)
170 {
171     FIXME("(%p)->(): Stub!\n", iface);
172
173     return E_NOTIMPL;
174 }
175
176 static HRESULT WINAPI MediaStreamFilterImpl_Pause(IMediaStreamFilter * iface)
177 {
178     FIXME("(%p)->(): Stub!\n", iface);
179
180     return E_NOTIMPL;
181 }
182
183 static HRESULT WINAPI MediaStreamFilterImpl_Run(IMediaStreamFilter * iface, REFERENCE_TIME tStart)
184 {
185     FIXME("(%p)->(%s): Stub!\n", iface, wine_dbgstr_longlong(tStart));
186
187     return E_NOTIMPL;
188 }
189
190 static HRESULT WINAPI MediaStreamFilterImpl_GetState(IMediaStreamFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState)
191 {
192     return BaseFilterImpl_GetState((IBaseFilter*)iface, dwMilliSecsTimeout, pState);
193 }
194
195 static HRESULT WINAPI MediaStreamFilterImpl_SetSyncSource(IMediaStreamFilter * iface, IReferenceClock *pClock)
196 {
197     return BaseFilterImpl_SetSyncSource((IBaseFilter*)iface, pClock);
198 }
199
200 static HRESULT WINAPI MediaStreamFilterImpl_GetSyncSource(IMediaStreamFilter * iface, IReferenceClock **ppClock)
201 {
202     return BaseFilterImpl_GetSyncSource((IBaseFilter*)iface, ppClock);
203 }
204
205 static HRESULT WINAPI MediaStreamFilterImpl_EnumPins(IMediaStreamFilter * iface, IEnumPins **ppEnum)
206 {
207     return BaseFilterImpl_EnumPins((IBaseFilter*)iface, ppEnum);
208 }
209
210 static HRESULT WINAPI MediaStreamFilterImpl_FindPin(IMediaStreamFilter * iface, LPCWSTR Id, IPin **ppPin)
211 {
212     FIXME("(%p)->(%s,%p): Stub!\n", iface, debugstr_w(Id), ppPin);
213
214     return E_NOTIMPL;
215 }
216
217 static HRESULT WINAPI MediaStreamFilterImpl_QueryFilterInfo(IMediaStreamFilter * iface, FILTER_INFO *pInfo)
218 {
219     return BaseFilterImpl_QueryFilterInfo((IBaseFilter*)iface, pInfo);
220 }
221
222 static HRESULT WINAPI MediaStreamFilterImpl_JoinFilterGraph(IMediaStreamFilter * iface, IFilterGraph *pGraph, LPCWSTR pName)
223 {
224     return BaseFilterImpl_JoinFilterGraph((IBaseFilter*)iface, pGraph, pName);
225 }
226
227 static HRESULT WINAPI MediaStreamFilterImpl_QueryVendorInfo(IMediaStreamFilter * iface, LPWSTR *pVendorInfo)
228 {
229     return BaseFilterImpl_QueryVendorInfo((IBaseFilter*)iface, pVendorInfo);
230 }
231
232 /*** IMediaStreamFilter methods ***/
233
234 static HRESULT WINAPI MediaStreamFilterImpl_AddMediaStream(IMediaStreamFilter* iface, IAMMediaStream *pAMMediaStream)
235 {
236     IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface);
237     IMediaStream** streams;
238     IPin** pins;
239     MediaStreamFilter_InputPin* pin;
240     HRESULT hr;
241     PIN_INFO info;
242     MSPID purpose_id;
243
244     TRACE("(%p)->(%p)\n", iface, pAMMediaStream);
245
246     streams = CoTaskMemRealloc(This->streams, (This->nb_streams + 1) * sizeof(IMediaStream*));
247     if (!streams)
248         return E_OUTOFMEMORY;
249     This->streams = streams;
250     pins = CoTaskMemRealloc(This->pins, (This->nb_streams + 1) * sizeof(IPin*));
251     if (!pins)
252         return E_OUTOFMEMORY;
253     This->pins = pins;
254     info.pFilter = (IBaseFilter*)&This->filter;
255     info.dir = PINDIR_INPUT;
256     hr = IAMMediaStream_GetInformation(pAMMediaStream, &purpose_id, NULL);
257     if (FAILED(hr))
258         return hr;
259     /* Pin name is "I{guid MSPID_PrimaryVideo or MSPID_PrimaryAudio}" */
260     info.achName[0] = 'I';
261     StringFromGUID2(&purpose_id, info.achName + 1, 40);
262     hr = BaseInputPin_Construct(&MediaStreamFilter_InputPin_Vtbl, &info, &input_BaseFuncTable, &input_BaseInputFuncTable, &This->filter.csFilter, NULL, &This->pins[This->nb_streams]);
263     if (FAILED(hr))
264         return hr;
265
266     pin = (MediaStreamFilter_InputPin*)This->pins[This->nb_streams];
267     pin->pin.pin.pinInfo.pFilter = (LPVOID)This;
268     This->streams[This->nb_streams] = (IMediaStream*)pAMMediaStream;
269     This->nb_streams++;
270
271     IMediaStream_AddRef((IMediaStream*)pAMMediaStream);
272
273     return S_OK;
274 }
275
276 static HRESULT WINAPI MediaStreamFilterImpl_GetMediaStream(IMediaStreamFilter* iface, REFMSPID idPurpose, IMediaStream **ppMediaStream)
277 {
278     IMediaStreamFilterImpl *This = impl_from_IMediaStreamFilter(iface);
279     MSPID purpose_id;
280     unsigned int i;
281
282     TRACE("(%p)->(%s,%p)\n", iface, debugstr_guid(idPurpose), ppMediaStream);
283
284     for (i = 0; i < This->nb_streams; i++)
285     {
286         IMediaStream_GetInformation(This->streams[i], &purpose_id, NULL);
287         if (IsEqualIID(&purpose_id, idPurpose))
288         {
289             *ppMediaStream = This->streams[i];
290             IMediaStream_AddRef(*ppMediaStream);
291             return S_OK;
292         }
293     }
294
295     return MS_E_NOSTREAM;
296 }
297
298 static HRESULT WINAPI MediaStreamFilterImpl_EnumMediaStreams(IMediaStreamFilter* iface, LONG Index, IMediaStream **ppMediaStream)
299 {
300     FIXME("(%p)->(%d,%p): Stub!\n", iface, Index, ppMediaStream);
301
302     return E_NOTIMPL;
303 }
304
305 static HRESULT WINAPI MediaStreamFilterImpl_SupportSeeking(IMediaStreamFilter* iface, BOOL bRenderer)
306 {
307     FIXME("(%p)->(%d): Stub!\n", iface, bRenderer);
308
309     return E_NOTIMPL;
310 }
311
312 static HRESULT WINAPI MediaStreamFilterImpl_ReferenceTimeToStreamTime(IMediaStreamFilter* iface, REFERENCE_TIME *pTime)
313 {
314     FIXME("(%p)->(%p): Stub!\n", iface, pTime);
315
316     return E_NOTIMPL;
317 }
318
319 static HRESULT WINAPI MediaStreamFilterImpl_GetCurrentStreamTime(IMediaStreamFilter* iface, REFERENCE_TIME *pCurrentStreamTime)
320 {
321     FIXME("(%p)->(%p): Stub!\n", iface, pCurrentStreamTime);
322
323     return E_NOTIMPL;
324 }
325
326 static HRESULT WINAPI MediaStreamFilterImpl_WaitUntil(IMediaStreamFilter* iface, REFERENCE_TIME WaitStreamTime)
327 {
328     FIXME("(%p)->(%s): Stub!\n", iface, wine_dbgstr_longlong(WaitStreamTime));
329
330     return E_NOTIMPL;
331 }
332
333 static HRESULT WINAPI MediaStreamFilterImpl_Flush(IMediaStreamFilter* iface, BOOL bCancelEOS)
334 {
335     FIXME("(%p)->(%d): Stub!\n", iface, bCancelEOS);
336
337     return E_NOTIMPL;
338 }
339
340 static HRESULT WINAPI MediaStreamFilterImpl_EndOfStream(IMediaStreamFilter* iface)
341 {
342     FIXME("(%p)->(): Stub!\n",  iface);
343
344     return E_NOTIMPL;
345 }
346
347 static const IMediaStreamFilterVtbl MediaStreamFilter_Vtbl =
348 {
349     MediaStreamFilterImpl_QueryInterface,
350     MediaStreamFilterImpl_AddRef,
351     MediaStreamFilterImpl_Release,
352     MediaStreamFilterImpl_GetClassID,
353     MediaStreamFilterImpl_Stop,
354     MediaStreamFilterImpl_Pause,
355     MediaStreamFilterImpl_Run,
356     MediaStreamFilterImpl_GetState,
357     MediaStreamFilterImpl_SetSyncSource,
358     MediaStreamFilterImpl_GetSyncSource,
359     MediaStreamFilterImpl_EnumPins,
360     MediaStreamFilterImpl_FindPin,
361     MediaStreamFilterImpl_QueryFilterInfo,
362     MediaStreamFilterImpl_JoinFilterGraph,
363     MediaStreamFilterImpl_QueryVendorInfo,
364     MediaStreamFilterImpl_AddMediaStream,
365     MediaStreamFilterImpl_GetMediaStream,
366     MediaStreamFilterImpl_EnumMediaStreams,
367     MediaStreamFilterImpl_SupportSeeking,
368     MediaStreamFilterImpl_ReferenceTimeToStreamTime,
369     MediaStreamFilterImpl_GetCurrentStreamTime,
370     MediaStreamFilterImpl_WaitUntil,
371     MediaStreamFilterImpl_Flush,
372     MediaStreamFilterImpl_EndOfStream
373 };
374
375 static IPin* WINAPI MediaStreamFilterImpl_GetPin(BaseFilter *iface, int pos)
376 {
377     IMediaStreamFilterImpl* This = (IMediaStreamFilterImpl*)iface;
378
379     if (pos < This->nb_streams)
380     {
381         IPin_AddRef(This->pins[pos]);
382         return This->pins[pos];
383     }
384
385     return NULL;
386 }
387
388 static LONG WINAPI MediaStreamFilterImpl_GetPinCount(BaseFilter *iface)
389 {
390     IMediaStreamFilterImpl* This = (IMediaStreamFilterImpl*)iface;
391
392     return This->nb_streams;
393 }
394
395 static const BaseFilterFuncTable BaseFuncTable = {
396     MediaStreamFilterImpl_GetPin,
397     MediaStreamFilterImpl_GetPinCount
398 };
399
400 HRESULT MediaStreamFilter_create(IUnknown *pUnkOuter, void **ppObj)
401 {
402     IMediaStreamFilterImpl* object;
403
404     TRACE("(%p,%p)\n", pUnkOuter, ppObj);
405
406     if( pUnkOuter )
407         return CLASS_E_NOAGGREGATION;
408
409     object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IMediaStreamFilterImpl));
410     if (!object)
411     {
412         ERR("Out of memory\n");
413         return E_OUTOFMEMORY;
414     }
415
416     BaseFilter_Init(&object->filter, (IBaseFilterVtbl*)&MediaStreamFilter_Vtbl, &CLSID_MediaStreamFilter, (DWORD_PTR)(__FILE__ ": MediaStreamFilterImpl.csFilter"), &BaseFuncTable);
417
418     *ppObj = object;
419
420     return S_OK;
421 }