msi: Add more join tests.
[wine/wine64.git] / dlls / qcap / capturegraph.c
bloba656ba26bd9c2e70e478b07b35fd5ec8feefd304
1 /* Capture Graph Builder, Minimal edition
3 * Copyright 2005 Maarten Lankhorst
4 * Copyright 2005 Rolf Kalbermatter
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.
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.
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
20 #include "config.h"
22 #include <stdio.h>
23 #include <stdarg.h>
25 #define COBJMACROS
26 #define NONAMELESSSTRUCT
27 #define NONAMELESSUNION
29 #include "windef.h"
30 #include "winbase.h"
31 #include "winerror.h"
32 #include "objbase.h"
33 #include "uuids.h"
35 #include "evcode.h"
36 #include "strmif.h"
37 #include "control.h"
39 *#include "amvideo.h"
40 *#include "mmreg.h"
41 *#include "vfwmsgs.h"
42 *#include "dshow.h"
43 *#include "ddraw.h"
45 #include "qcap_main.h"
47 #include "wine/unicode.h"
48 #include "wine/debug.h"
50 WINE_DEFAULT_DEBUG_CHANNEL(qcap);
52 /***********************************************************************
53 * ICaptureGraphBuilder & ICaptureGraphBuilder2 implementation
55 typedef struct CaptureGraphImpl
57 const ICaptureGraphBuilder2Vtbl * lpVtbl2;
58 const ICaptureGraphBuilderVtbl * lpVtbl;
59 LONG ref;
60 IGraphBuilder *mygraph;
62 CRITICAL_SECTION csFilter;
63 } CaptureGraphImpl;
65 static const ICaptureGraphBuilderVtbl builder_Vtbl;
66 static const ICaptureGraphBuilder2Vtbl builder2_Vtbl;
68 static inline CaptureGraphImpl *impl_from_ICaptureGraphBuilder( ICaptureGraphBuilder *iface )
70 return (CaptureGraphImpl *)((char*)iface - FIELD_OFFSET(CaptureGraphImpl, lpVtbl));
73 static inline CaptureGraphImpl *impl_from_ICaptureGraphBuilder2( ICaptureGraphBuilder2 *iface )
75 return (CaptureGraphImpl *)((char*)iface - FIELD_OFFSET(CaptureGraphImpl, lpVtbl2));
79 converts This to an interface pointer
81 #define _IUnknown_(This) (IUnknown*)&(This->lpVtbl2)
82 #define _ICaptureGraphBuilder_(This) (ICaptureGraphBuilder*)&(This->lpVtbl)
83 #define _ICaptureGraphBuilder2_(This) (ICaptureGraphBuilder2*)&(This->lpVtbl2)
86 IUnknown * CALLBACK QCAP_createCaptureGraphBuilder2(IUnknown *pUnkOuter,
87 HRESULT *phr)
89 CaptureGraphImpl * pCapture = NULL;
91 TRACE("(%p, %p)\n", pUnkOuter, phr);
93 *phr = CLASS_E_NOAGGREGATION;
94 if (pUnkOuter)
96 return NULL;
98 *phr = E_OUTOFMEMORY;
100 pCapture = CoTaskMemAlloc(sizeof(CaptureGraphImpl));
101 if (pCapture)
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);
111 return (IUnknown *)pCapture;
114 static HRESULT WINAPI
115 fnCaptureGraphBuilder2_QueryInterface(ICaptureGraphBuilder2 * iface,
116 REFIID riid,
117 LPVOID * ppv)
119 CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);
121 TRACE("(%p/%p)->(%s, %p)\n", This, iface, debugstr_guid(riid), ppv);
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);
131 if (*ppv)
133 IUnknown_AddRef((IUnknown *)(*ppv));
134 TRACE ("-- Interface = %p\n", *ppv);
135 return S_OK;
138 TRACE ("-- Interface: E_NOINTERFACE\n");
139 return E_NOINTERFACE;
142 static ULONG WINAPI
143 fnCaptureGraphBuilder2_AddRef(ICaptureGraphBuilder2 * iface)
145 CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);
146 DWORD ref = InterlockedIncrement(&This->ref);
148 TRACE("(%p/%p)->() AddRef from %ld\n", This, iface, ref - 1);
149 return ref;
152 static ULONG WINAPI
153 fnCaptureGraphBuilder2_Release(ICaptureGraphBuilder2 * iface)
155 CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);
156 DWORD ref = InterlockedDecrement(&This->ref);
158 TRACE("(%p/%p)->() Release from %ld\n", This, iface, ref + 1);
160 if (!ref)
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);
171 return ref;
174 static HRESULT WINAPI
175 fnCaptureGraphBuilder2_SetFilterGraph(ICaptureGraphBuilder2 * iface,
176 IGraphBuilder *pfg)
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);
184 TRACE("(%p/%p)->(%p)\n", This, iface, pfg);
186 if (This->mygraph)
187 return E_UNEXPECTED;
189 if (!pfg)
190 return E_POINTER;
192 This->mygraph = pfg;
193 IGraphBuilder_AddRef((IGraphBuilder *)This->mygraph);
194 if (SUCCEEDED(IUnknown_QueryInterface(This->mygraph,
195 &IID_IMediaEvent, (LPVOID *)&pmev)))
197 IMediaEvent_CancelDefaultHandling(pmev, EC_REPAINT);
198 IMediaEvent_Release(pmev);
200 return S_OK;
203 static HRESULT WINAPI
204 fnCaptureGraphBuilder2_GetFilterGraph(ICaptureGraphBuilder2 * iface,
205 IGraphBuilder **pfg)
207 CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);
209 TRACE("(%p/%p)->(%p)\n", This, iface, pfg);
211 if (!pfg)
212 return E_POINTER;
214 *pfg = This->mygraph;
215 if (!This->mygraph)
217 TRACE("(%p) Getting NULL filtergraph\n", iface);
218 return E_UNEXPECTED;
221 IGraphBuilder_AddRef((IGraphBuilder *)This->mygraph);
223 TRACE("(%p) return filtergraph %p\n", iface, *pfg);
224 return S_OK;
227 static HRESULT WINAPI
228 fnCaptureGraphBuilder2_SetOutputFileName(ICaptureGraphBuilder2 * iface,
229 const GUID *pType,
230 LPCOLESTR lpstrFile,
231 IBaseFilter **ppf,
232 IFileSinkFilter **ppSink)
234 CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);
236 FIXME("(%p/%p)->(%s, %s, %p, %p) Stub!\n", This, iface,
237 debugstr_guid(pType), debugstr_w(lpstrFile), ppf, ppSink);
239 return E_NOTIMPL;
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)
250 CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);
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);
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.
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)
271 CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);
273 FIXME("(%p/%p)->(%s, %s, %p, %p, %p) Stub!\n", This, iface,
274 debugstr_guid(pCategory), debugstr_guid(pType),
275 pSource, pfCompressor, pfRenderer);
277 return E_NOTIMPL;
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)
290 CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);
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);
296 return E_NOTIMPL;
299 static HRESULT WINAPI
300 fnCaptureGraphBuilder2_AllocCapFile(ICaptureGraphBuilder2 * iface,
301 LPCOLESTR lpwstr,
302 DWORDLONG dwlSize)
304 CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);
306 FIXME("(%p/%p)->(%s, 0x%s) Stub!\n", This, iface,
307 debugstr_w(lpwstr), wine_dbgstr_longlong(dwlSize));
309 return E_NOTIMPL;
312 static HRESULT WINAPI
313 fnCaptureGraphBuilder2_CopyCaptureFile(ICaptureGraphBuilder2 * iface,
314 LPOLESTR lpwstrOld,
315 LPOLESTR lpwstrNew,
316 int fAllowEscAbort,
317 IAMCopyCaptureFileProgress *pCallback)
319 CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);
321 FIXME("(%p/%p)->(%s, %s, %i, %p) Stub!\n", This, iface,
322 debugstr_w(lpwstrOld), debugstr_w(lpwstrNew),
323 fAllowEscAbort, pCallback);
325 return E_NOTIMPL;
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)
338 CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);
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);
344 return E_NOTIMPL;
347 static const ICaptureGraphBuilder2Vtbl builder2_Vtbl =
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
364 static HRESULT WINAPI
365 fnCaptureGraphBuilder_QueryInterface(ICaptureGraphBuilder * iface,
366 REFIID riid, LPVOID * ppv)
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);
373 static ULONG WINAPI
374 fnCaptureGraphBuilder_AddRef(ICaptureGraphBuilder * iface)
376 CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder(iface);
377 TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
378 return IUnknown_AddRef(_ICaptureGraphBuilder2_(This));
381 static ULONG WINAPI
382 fnCaptureGraphBuilder_Release(ICaptureGraphBuilder * iface)
384 CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder(iface);
385 TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
386 return IUnknown_Release(_ICaptureGraphBuilder2_(This));
389 static HRESULT WINAPI
390 fnCaptureGraphBuilder_SetFiltergraph(ICaptureGraphBuilder * iface,
391 IGraphBuilder *pfg)
393 CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder(iface);
394 TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
395 return ICaptureGraphBuilder2_SetFiltergraph(_ICaptureGraphBuilder2_(This), pfg);
398 static HRESULT WINAPI
399 fnCaptureGraphBuilder_GetFiltergraph(ICaptureGraphBuilder * iface,
400 IGraphBuilder **pfg)
402 CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder(iface);
403 TRACE("%p --> Forwarding to v2 (%p)\n", iface, This);
404 return ICaptureGraphBuilder2_GetFiltergraph(_ICaptureGraphBuilder2_(This), pfg);
407 static HRESULT WINAPI
408 fnCaptureGraphBuilder_SetOutputFileName(ICaptureGraphBuilder * iface,
409 const GUID *pType, LPCOLESTR lpstrFile,
410 IBaseFilter **ppf, IFileSinkFilter **ppSink)
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);
418 static HRESULT WINAPI
419 fnCaptureGraphBuilder_FindInterface(ICaptureGraphBuilder * iface,
420 const GUID *pCategory, IBaseFilter *pf,
421 REFIID riid, void **ppint)
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);
429 static HRESULT WINAPI
430 fnCaptureGraphBuilder_RenderStream(ICaptureGraphBuilder * iface,
431 const GUID *pCategory, IUnknown *pSource,
432 IBaseFilter *pfCompressor, IBaseFilter *pfRenderer)
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);
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)
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);
454 static HRESULT WINAPI
455 fnCaptureGraphBuilder_AllocCapFile(ICaptureGraphBuilder * iface,
456 LPCOLESTR lpstr, DWORDLONG dwlSize)
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);
464 static HRESULT WINAPI
465 fnCaptureGraphBuilder_CopyCaptureFile(ICaptureGraphBuilder * iface,
466 LPOLESTR lpwstrOld, LPOLESTR lpwstrNew,
467 int fAllowEscAbort,
468 IAMCopyCaptureFileProgress *pCallback)
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);
477 static const ICaptureGraphBuilderVtbl builder_Vtbl =
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