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