mcicda: Exclude unused headers.
[wine] / dlls / qcap / capturegraph.c
1 /* Capture Graph Builder, Minimal edition
2  *
3  * Copyright 2005 Maarten Lankhorst
4  * Copyright 2005 Rolf Kalbermatter
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 #include "config.h"
21
22 #include <stdio.h>
23 #include <stdarg.h>
24
25 #define COBJMACROS
26 #define NONAMELESSSTRUCT
27 #define NONAMELESSUNION
28
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winerror.h"
32 #include "objbase.h"
33 #include "uuids.h"
34
35 #include "evcode.h"
36 #include "strmif.h"
37 #include "control.h"
38 /*
39  *#include "amvideo.h"
40  *#include "mmreg.h"
41  *#include "vfwmsgs.h"
42  *#include "dshow.h"
43  *#include "ddraw.h"
44  */
45 #include "qcap_main.h"
46
47 #include "wine/unicode.h"
48 #include "wine/debug.h"
49
50 WINE_DEFAULT_DEBUG_CHANNEL(qcap);
51
52 /***********************************************************************
53 *   ICaptureGraphBuilder & ICaptureGraphBuilder2 implementation
54 */
55 typedef struct CaptureGraphImpl
56 {
57     const ICaptureGraphBuilder2Vtbl * lpVtbl2;
58     const ICaptureGraphBuilderVtbl * lpVtbl;
59     LONG ref;
60     IGraphBuilder *mygraph;
61
62     CRITICAL_SECTION csFilter;
63 } CaptureGraphImpl;
64
65 static const ICaptureGraphBuilderVtbl builder_Vtbl;
66 static const ICaptureGraphBuilder2Vtbl builder2_Vtbl;
67
68 static inline CaptureGraphImpl *impl_from_ICaptureGraphBuilder( ICaptureGraphBuilder *iface )
69 {
70     return (CaptureGraphImpl *)((char*)iface - FIELD_OFFSET(CaptureGraphImpl, lpVtbl));
71 }
72
73 static inline CaptureGraphImpl *impl_from_ICaptureGraphBuilder2( ICaptureGraphBuilder2 *iface )
74 {
75     return (CaptureGraphImpl *)((char*)iface - FIELD_OFFSET(CaptureGraphImpl, lpVtbl2));
76 }
77
78 /*
79   converts This to an interface pointer
80 */
81 #define _IUnknown_(This)                (IUnknown*)&(This->lpVtbl2)
82 #define _ICaptureGraphBuilder_(This)    (ICaptureGraphBuilder*)&(This->lpVtbl)
83 #define _ICaptureGraphBuilder2_(This)   (ICaptureGraphBuilder2*)&(This->lpVtbl2)
84
85
86 IUnknown * CALLBACK QCAP_createCaptureGraphBuilder2(IUnknown *pUnkOuter,
87                                                     HRESULT *phr)
88 {
89     CaptureGraphImpl * pCapture = NULL;
90
91     TRACE("(%p, %p)\n", pUnkOuter, phr);
92
93     *phr = CLASS_E_NOAGGREGATION;
94     if (pUnkOuter)
95     {
96         return NULL;
97     }
98     *phr = E_OUTOFMEMORY;
99
100     pCapture = CoTaskMemAlloc(sizeof(CaptureGraphImpl));
101     if (pCapture)
102     {
103         pCapture->lpVtbl2 = &builder2_Vtbl;
104         pCapture->lpVtbl = &builder_Vtbl;
105         pCapture->ref = 1;
106         pCapture->mygraph = NULL;
107         InitializeCriticalSection(&pCapture->csFilter);
108         pCapture->csFilter.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": CaptureGraphImpl.csFilter");
109         *phr = S_OK;
110         ObjectRefCount(TRUE);
111     }
112     return (IUnknown *)pCapture;
113 }
114
115 static HRESULT WINAPI
116 fnCaptureGraphBuilder2_QueryInterface(ICaptureGraphBuilder2 * iface,
117                                       REFIID riid,
118                                       LPVOID * ppv)
119 {
120     CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);
121
122     TRACE("(%p/%p)->(%s, %p)\n", This, iface, debugstr_guid(riid), ppv);
123
124     *ppv = NULL;
125     if (IsEqualIID(riid, &IID_IUnknown))
126         *ppv = _IUnknown_(This);
127     else if (IsEqualIID(riid, &IID_ICaptureGraphBuilder))
128         *ppv = _ICaptureGraphBuilder_(This);
129     else if (IsEqualIID(riid, &IID_ICaptureGraphBuilder2))
130         *ppv = _ICaptureGraphBuilder2_(This);
131
132     if (*ppv)
133     {
134         IUnknown_AddRef((IUnknown *)(*ppv));
135         TRACE ("-- Interface = %p\n", *ppv);
136         return S_OK;
137     }
138
139     TRACE ("-- Interface: E_NOINTERFACE\n");
140     return E_NOINTERFACE;
141 }
142
143 static ULONG WINAPI
144 fnCaptureGraphBuilder2_AddRef(ICaptureGraphBuilder2 * iface)
145 {
146     CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);
147     DWORD ref = InterlockedIncrement(&This->ref);
148
149     TRACE("(%p/%p)->() AddRef from %d\n", This, iface, ref - 1);
150     return ref;
151 }
152
153 static ULONG WINAPI
154 fnCaptureGraphBuilder2_Release(ICaptureGraphBuilder2 * iface)
155 {
156     CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);
157     DWORD ref = InterlockedDecrement(&This->ref);
158
159     TRACE("(%p/%p)->() Release from %d\n", This, iface, ref + 1);
160
161     if (!ref)
162     {
163         FIXME("Release IGraphFilter or w/e\n");
164         This->csFilter.DebugInfo->Spare[0] = 0;
165         DeleteCriticalSection(&This->csFilter);
166         This->lpVtbl = NULL;
167         This->lpVtbl2 = NULL;
168         if (This->mygraph != NULL)
169             IGraphBuilder_Release((IGraphBuilder *)This->mygraph);
170         CoTaskMemFree(This);
171         ObjectRefCount(FALSE);
172     }
173     return ref;
174 }
175
176 static HRESULT WINAPI
177 fnCaptureGraphBuilder2_SetFilterGraph(ICaptureGraphBuilder2 * iface,
178                                       IGraphBuilder *pfg)
179 {
180 /* The graph builder will automatically create a filter graph if you don't call
181    this method. If you call this method after the graph builder has created its
182    own filter graph, the call will fail. */
183     IMediaEvent *pmev;
184     CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);
185
186     TRACE("(%p/%p)->(%p)\n", This, iface, pfg);
187
188     if (This->mygraph)
189         return E_UNEXPECTED;
190
191     if (!pfg)
192         return E_POINTER;
193
194     This->mygraph = pfg;
195     IGraphBuilder_AddRef((IGraphBuilder *)This->mygraph);
196     if (SUCCEEDED(IUnknown_QueryInterface(This->mygraph,
197                                           &IID_IMediaEvent, (LPVOID *)&pmev)))
198     {
199         IMediaEvent_CancelDefaultHandling(pmev, EC_REPAINT);
200         IMediaEvent_Release(pmev);
201     }
202     return S_OK;
203 }
204
205 static HRESULT WINAPI
206 fnCaptureGraphBuilder2_GetFilterGraph(ICaptureGraphBuilder2 * iface,
207                                       IGraphBuilder **pfg)
208 {
209     CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);
210
211     TRACE("(%p/%p)->(%p)\n", This, iface, pfg);
212
213     if (!pfg)
214         return E_POINTER;
215
216     *pfg = This->mygraph;
217     if (!This->mygraph)
218     {
219         TRACE("(%p) Getting NULL filtergraph\n", iface);
220         return E_UNEXPECTED;
221     }
222
223     IGraphBuilder_AddRef((IGraphBuilder *)This->mygraph);
224    
225     TRACE("(%p) return filtergraph %p\n", iface, *pfg);
226     return S_OK;
227 }
228
229 static HRESULT WINAPI
230 fnCaptureGraphBuilder2_SetOutputFileName(ICaptureGraphBuilder2 * iface,
231                                          const GUID *pType,
232                                          LPCOLESTR lpstrFile,
233                                          IBaseFilter **ppf,
234                                          IFileSinkFilter **ppSink)
235 {
236     CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);
237
238     FIXME("(%p/%p)->(%s, %s, %p, %p) Stub!\n", This, iface,
239           debugstr_guid(pType), debugstr_w(lpstrFile), ppf, ppSink);
240
241     return E_NOTIMPL;
242 }
243
244 static HRESULT WINAPI
245 fnCaptureGraphBuilder2_FindInterface(ICaptureGraphBuilder2 * iface,
246                                      const GUID *pCategory,
247                                      const GUID *pType,
248                                      IBaseFilter *pf,
249                                      REFIID riid,
250                                      void **ppint)
251 {
252     CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);
253
254     FIXME("(%p/%p)->(%s, %s, %p, %s, %p) - workaround stub!\n", This, iface,
255           debugstr_guid(pCategory), debugstr_guid(pType),
256           pf, debugstr_guid(riid), ppint);
257
258     return IBaseFilter_QueryInterface(pf, riid, ppint);
259     /* Looks for the specified interface on the filter, upstream and
260      * downstream from the filter, and, optionally, only on the output
261      * pin of the given category.
262      */
263 }
264
265 static HRESULT WINAPI
266 fnCaptureGraphBuilder2_RenderStream(ICaptureGraphBuilder2 * iface,
267                                     const GUID *pCategory,
268                                     const GUID *pType,
269                                     IUnknown *pSource,
270                                     IBaseFilter *pfCompressor,
271                                     IBaseFilter *pfRenderer)
272 {
273     CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);
274
275     FIXME("(%p/%p)->(%s, %s, %p, %p, %p) Stub!\n", This, iface,
276           debugstr_guid(pCategory), debugstr_guid(pType),
277           pSource, pfCompressor, pfRenderer);
278
279     return E_NOTIMPL;
280 }
281
282 static HRESULT WINAPI
283 fnCaptureGraphBuilder2_ControlStream(ICaptureGraphBuilder2 * iface,
284                                      const GUID *pCategory,
285                                      const GUID *pType,
286                                      IBaseFilter *pFilter,
287                                      REFERENCE_TIME *pstart,
288                                      REFERENCE_TIME *pstop,
289                                      WORD wStartCookie,
290                                      WORD wStopCookie)
291 {
292     CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);
293
294     FIXME("(%p/%p)->(%s, %s, %p, %p, %p, %i, %i) Stub!\n", This, iface,
295           debugstr_guid(pCategory), debugstr_guid(pType),
296           pFilter, pstart, pstop, wStartCookie, wStopCookie);
297
298     return E_NOTIMPL;
299 }
300
301 static HRESULT WINAPI
302 fnCaptureGraphBuilder2_AllocCapFile(ICaptureGraphBuilder2 * iface,
303                                     LPCOLESTR lpwstr,
304                                     DWORDLONG dwlSize)
305 {
306     CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);
307
308     FIXME("(%p/%p)->(%s, 0x%s) Stub!\n", This, iface,
309           debugstr_w(lpwstr), wine_dbgstr_longlong(dwlSize));
310
311     return E_NOTIMPL;
312 }
313
314 static HRESULT WINAPI
315 fnCaptureGraphBuilder2_CopyCaptureFile(ICaptureGraphBuilder2 * iface,
316                                        LPOLESTR lpwstrOld,
317                                        LPOLESTR lpwstrNew,
318                                        int fAllowEscAbort,
319                                        IAMCopyCaptureFileProgress *pCallback)
320 {
321     CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);
322
323     FIXME("(%p/%p)->(%s, %s, %i, %p) Stub!\n", This, iface,
324           debugstr_w(lpwstrOld), debugstr_w(lpwstrNew),
325           fAllowEscAbort, pCallback);
326
327     return E_NOTIMPL;
328 }
329
330 static HRESULT WINAPI
331 fnCaptureGraphBuilder2_FindPin(ICaptureGraphBuilder2 * iface,
332                                IUnknown *pSource,
333                                PIN_DIRECTION pindir,
334                                const GUID *pCategory,
335                                const GUID *pType,
336                                BOOL fUnconnected,
337                                int num,
338                                IPin **ppPin)
339 {
340     CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);
341
342     FIXME("(%p/%p)->(%p, %x, %s, %s, %d, %i, %p) Stub!\n", This, iface,
343           pSource, pindir, debugstr_guid(pCategory), debugstr_guid(pType),
344           fUnconnected, num, ppPin);
345
346     return E_NOTIMPL;
347 }
348
349 static const ICaptureGraphBuilder2Vtbl builder2_Vtbl =
350 {   
351     fnCaptureGraphBuilder2_QueryInterface,
352     fnCaptureGraphBuilder2_AddRef,
353     fnCaptureGraphBuilder2_Release,
354     fnCaptureGraphBuilder2_SetFilterGraph,
355     fnCaptureGraphBuilder2_GetFilterGraph,
356     fnCaptureGraphBuilder2_SetOutputFileName,
357     fnCaptureGraphBuilder2_FindInterface,
358     fnCaptureGraphBuilder2_RenderStream,
359     fnCaptureGraphBuilder2_ControlStream,
360     fnCaptureGraphBuilder2_AllocCapFile,
361     fnCaptureGraphBuilder2_CopyCaptureFile,
362     fnCaptureGraphBuilder2_FindPin
363 };
364
365
366 static HRESULT WINAPI
367 fnCaptureGraphBuilder_QueryInterface(ICaptureGraphBuilder * iface,
368                                      REFIID riid, LPVOID * ppv)
369 {
370     CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder(iface);
371     TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
372     return IUnknown_QueryInterface(_ICaptureGraphBuilder2_(This), riid, ppv);
373 }
374
375 static ULONG WINAPI
376 fnCaptureGraphBuilder_AddRef(ICaptureGraphBuilder * iface)
377 {
378     CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder(iface);
379     TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
380     return IUnknown_AddRef(_ICaptureGraphBuilder2_(This));
381 }
382
383 static ULONG WINAPI
384 fnCaptureGraphBuilder_Release(ICaptureGraphBuilder * iface)
385 {
386     CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder(iface);
387     TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
388     return IUnknown_Release(_ICaptureGraphBuilder2_(This));
389 }
390
391 static HRESULT WINAPI
392 fnCaptureGraphBuilder_SetFiltergraph(ICaptureGraphBuilder * iface,
393                                      IGraphBuilder *pfg)
394 {
395     CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder(iface);
396     TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
397     return ICaptureGraphBuilder2_SetFiltergraph(_ICaptureGraphBuilder2_(This), pfg);
398 }
399
400 static HRESULT WINAPI
401 fnCaptureGraphBuilder_GetFiltergraph(ICaptureGraphBuilder * iface,
402                                      IGraphBuilder **pfg)
403 {
404     CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder(iface);
405     TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
406     return ICaptureGraphBuilder2_GetFiltergraph(_ICaptureGraphBuilder2_(This), pfg);
407 }
408
409 static HRESULT WINAPI
410 fnCaptureGraphBuilder_SetOutputFileName(ICaptureGraphBuilder * iface,
411                                         const GUID *pType, LPCOLESTR lpstrFile,
412                                         IBaseFilter **ppf, IFileSinkFilter **ppSink)
413 {
414     CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder(iface);
415     TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
416     return ICaptureGraphBuilder2_SetOutputFileName(_ICaptureGraphBuilder2_(This),
417                                                    pType, lpstrFile, ppf, ppSink);
418 }
419
420 static HRESULT WINAPI
421 fnCaptureGraphBuilder_FindInterface(ICaptureGraphBuilder * iface,
422                                     const GUID *pCategory, IBaseFilter *pf,
423                                     REFIID riid, void **ppint)
424 {
425     CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder(iface);
426     TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
427     return ICaptureGraphBuilder2_FindInterface(_ICaptureGraphBuilder2_(This),
428                                                pCategory, NULL, pf, riid, ppint);
429 }
430
431 static HRESULT WINAPI
432 fnCaptureGraphBuilder_RenderStream(ICaptureGraphBuilder * iface,
433                                    const GUID *pCategory, IUnknown *pSource,
434                                    IBaseFilter *pfCompressor, IBaseFilter *pfRenderer)
435 {
436     CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder(iface);
437     TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
438     return ICaptureGraphBuilder2_RenderStream(_ICaptureGraphBuilder2_(This),
439                                               pCategory, NULL, pSource,
440                                               pfCompressor, pfRenderer);
441 }
442
443 static HRESULT WINAPI
444 fnCaptureGraphBuilder_ControlStream(ICaptureGraphBuilder * iface,
445                                     const GUID *pCategory, IBaseFilter *pFilter,
446                                     REFERENCE_TIME *pstart, REFERENCE_TIME *pstop,
447                                     WORD wStartCookie, WORD wStopCookie)
448 {
449     CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder(iface);
450     TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
451     return ICaptureGraphBuilder2_ControlStream(_ICaptureGraphBuilder2_(This),
452                                                pCategory, NULL, pFilter, pstart, 
453                                                pstop, wStartCookie, wStopCookie);
454 }
455
456 static HRESULT WINAPI
457 fnCaptureGraphBuilder_AllocCapFile(ICaptureGraphBuilder * iface,
458                                    LPCOLESTR lpstr, DWORDLONG dwlSize)
459 {
460     CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder(iface);
461     TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
462     return ICaptureGraphBuilder2_AllocCapFile(_ICaptureGraphBuilder2_(This),
463                                               lpstr, dwlSize);
464 }
465
466 static HRESULT WINAPI
467 fnCaptureGraphBuilder_CopyCaptureFile(ICaptureGraphBuilder * iface,
468                                       LPOLESTR lpwstrOld, LPOLESTR lpwstrNew,
469                                       int fAllowEscAbort,
470                                       IAMCopyCaptureFileProgress *pCallback)
471 {
472     CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder(iface);
473     TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
474     return ICaptureGraphBuilder2_CopyCaptureFile(_ICaptureGraphBuilder2_(This),
475                                                  lpwstrOld, lpwstrNew,
476                                                  fAllowEscAbort, pCallback);
477 }
478
479 static const ICaptureGraphBuilderVtbl builder_Vtbl =
480 {   
481    fnCaptureGraphBuilder_QueryInterface,
482    fnCaptureGraphBuilder_AddRef,
483    fnCaptureGraphBuilder_Release,
484    fnCaptureGraphBuilder_SetFiltergraph,
485    fnCaptureGraphBuilder_GetFiltergraph,
486    fnCaptureGraphBuilder_SetOutputFileName,
487    fnCaptureGraphBuilder_FindInterface,
488    fnCaptureGraphBuilder_RenderStream,
489    fnCaptureGraphBuilder_ControlStream,
490    fnCaptureGraphBuilder_AllocCapFile,
491    fnCaptureGraphBuilder_CopyCaptureFile
492 };