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