From 84e00d48042eec3a6ac2f18cfaf01e7c3566a36a Mon Sep 17 00:00:00 2001 From: Rolf Kalbermatter Date: Sat, 7 May 2005 18:18:39 +0000 Subject: [PATCH] Implement ICaptureGraphBuilder and IcaptureGraphBuilder2 based on Maarten Lankhorst's patch. --- dlls/qcap/Makefile.in | 1 + dlls/qcap/capturegraph.c | 488 +++++++++++++++++++++++++++++++++++++++ dlls/qcap/qcap_main.c | 4 +- 3 files changed, 491 insertions(+), 2 deletions(-) create mode 100644 dlls/qcap/capturegraph.c diff --git a/dlls/qcap/Makefile.in b/dlls/qcap/Makefile.in index 6055673d5e0..11097479714 100644 --- a/dlls/qcap/Makefile.in +++ b/dlls/qcap/Makefile.in @@ -7,6 +7,7 @@ IMPORTS = ole32 oleaut32 user32 advapi32 kernel32 EXTRALIBS = -lstrmiids -luuid $(LIBUNICODE) C_SRCS = \ + capturegraph.c \ dllsetup.c \ qcap_main.c diff --git a/dlls/qcap/capturegraph.c b/dlls/qcap/capturegraph.c new file mode 100644 index 00000000000..2c75ba4e4f8 --- /dev/null +++ b/dlls/qcap/capturegraph.c @@ -0,0 +1,488 @@ +/* Capture Graph Builder, Minimal edition + * + * Copyright 2005 Maarten Lankhorst + * Copyright 2005 Rolf Kalbermatter + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#include "config.h" + +#include +#include + +#define COBJMACROS +#define NONAMELESSSTRUCT +#define NONAMELESSUNION + +#include "windef.h" +#include "winbase.h" +#include "winerror.h" +#include "objbase.h" +#include "uuids.h" + +#include "evcode.h" +#include "strmif.h" +#include "control.h" +/* + *#include "amvideo.h" + *#include "mmreg.h" + *#include "vfwmsgs.h" + *#include "dshow.h" + *#include "ddraw.h" + */ +#include "qcap_main.h" + +#include "wine/unicode.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(quartz); + +static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0}; + +/*********************************************************************** +* ICaptureGraphBuilder & ICaptureGraphBuilder2 implementation +*/ +typedef struct CaptureGraphImpl +{ + const ICaptureGraphBuilder2Vtbl * lpVtbl2; + const ICaptureGraphBuilderVtbl * lpVtbl; + DWORD ref; + IGraphBuilder *mygraph; + + CRITICAL_SECTION csFilter; +} CaptureGraphImpl; + +static const ICaptureGraphBuilderVtbl builder_Vtbl; +static const ICaptureGraphBuilder2Vtbl builder2_Vtbl; + +#define _ICaptureGraphBuilder_Offset ((int)(&(((CaptureGraphImpl*)0)->lpVtbl))) +#define _ICOM_THIS_From_ICaptureGraphBuilder(class, name) class* This = (class*)(((char*)name)-_ICaptureGraphBuilder_Offset) + +#define _ICaptureGraphBuilder2_Offset ((int)(&(((CaptureGraphImpl*)0)->lpVtbl2))) +#define _ICOM_THIS_From_ICaptureGraphBuilder2(class, name) class* This = (class*)(((char*)name)-_ICaptureGraphBuilder2_Offset) + +/* + converts This to an interface pointer +*/ +#define _IUnknown_(This) (IUnknown*)&(This->lpVtbl2) +#define _ICaptureGraphBuilder_(This) (ICaptureGraphBuilder*)&(This->lpVtbl) +#define _ICaptureGraphBuilder2_(This) (ICaptureGraphBuilder2*)&(This->lpVtbl2) + + +IUnknown * CALLBACK QCAP_createCaptureGraphBuilder2(IUnknown *pUnkOuter, + HRESULT *phr) +{ + CaptureGraphImpl * pCapture = NULL; + + TRACE("(%p, %p)\n", pUnkOuter, phr); + + *phr = CLASS_E_NOAGGREGATION; + if (pUnkOuter) + { + return NULL; + } + *phr = E_OUTOFMEMORY; + + pCapture = CoTaskMemAlloc(sizeof(CaptureGraphImpl)); + if (pCapture) + { + pCapture->lpVtbl2 = &builder2_Vtbl; + pCapture->lpVtbl = &builder_Vtbl; + pCapture->ref = 1; + pCapture->mygraph = NULL; + InitializeCriticalSection(&pCapture->csFilter); + *phr = S_OK; + } + return (IUnknown *)pCapture; +} + +static HRESULT WINAPI +fnCaptureGraphBuilder2_QueryInterface(ICaptureGraphBuilder2 * iface, + REFIID riid, + LPVOID * ppv) +{ + _ICOM_THIS_From_ICaptureGraphBuilder2(CaptureGraphImpl, iface); + + TRACE("(%p/%p)->(%s, %p)\n", This, iface, debugstr_guid(riid), ppv); + + *ppv = NULL; + if (IsEqualIID(riid, &IID_IUnknown)) + *ppv = _IUnknown_(This); + else if (IsEqualIID(riid, &IID_ICaptureGraphBuilder)) + *ppv = _ICaptureGraphBuilder_(This); + else if (IsEqualIID(riid, &IID_ICaptureGraphBuilder2)) + *ppv = _ICaptureGraphBuilder2_(This); + + if (*ppv) + { + IUnknown_AddRef((IUnknown *)(*ppv)); + TRACE ("-- Interface = %p\n", *ppv); + return S_OK; + } + + TRACE ("-- Interface: E_NOINTERFACE\n"); + return E_NOINTERFACE; +} + +static ULONG WINAPI +fnCaptureGraphBuilder2_AddRef(ICaptureGraphBuilder2 * iface) +{ + _ICOM_THIS_From_ICaptureGraphBuilder2(CaptureGraphImpl, iface); + DWORD ref = InterlockedIncrement(&This->ref); + + TRACE("(%p/%p)->() AddRef from %ld\n", This, iface, ref - 1); + return ref; +} + +static ULONG WINAPI +fnCaptureGraphBuilder2_Release(ICaptureGraphBuilder2 * iface) +{ + _ICOM_THIS_From_ICaptureGraphBuilder2(CaptureGraphImpl, iface); + DWORD ref = InterlockedDecrement(&This->ref); + + TRACE("(%p/%p)->() Release from %ld\n", This, iface, ref + 1); + + if (!ref) + { + FIXME("Release IGraphFilter or w/e\n"); + DeleteCriticalSection(&This->csFilter); + This->lpVtbl = NULL; + This->lpVtbl2 = NULL; + if (This->mygraph != NULL) + IGraphBuilder_Release((IGraphBuilder *)This->mygraph); + CoTaskMemFree(This); + return 0; + } + else + return ref; +} + +static HRESULT WINAPI +fnCaptureGraphBuilder2_SetFilterGraph(ICaptureGraphBuilder2 * iface, + IGraphBuilder *pfg) +{ +/* The graph builder will automatically create a filter graph if you don't call + this method. If you call this method after the graph builder has created its + own filter graph, the call will fail. */ + IMediaEvent *pmev; + _ICOM_THIS_From_ICaptureGraphBuilder2(CaptureGraphImpl, iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pfg); + + if (!This->mygraph) + return E_UNEXPECTED; + + if (!pfg) + return E_POINTER; + + This->mygraph = pfg; + IGraphBuilder_AddRef((IGraphBuilder *)This->mygraph); + if (SUCCEEDED(IUnknown_QueryInterface(This->mygraph, + &IID_IMediaEvent, (LPVOID *)&pmev))) + { + IMediaEvent_CancelDefaultHandling(pmev, EC_REPAINT); + IMediaEvent_Release(pmev); + } + return S_OK; +} + +static HRESULT WINAPI +fnCaptureGraphBuilder2_GetFilterGraph(ICaptureGraphBuilder2 * iface, + IGraphBuilder **pfg) +{ + _ICOM_THIS_From_ICaptureGraphBuilder2(CaptureGraphImpl, iface); + + TRACE("(%p/%p)->(%p)\n", This, iface, pfg); + + if (!pfg) + return E_POINTER; + + *pfg = This->mygraph; + if (!This->mygraph) + { + TRACE("(%p) Getting NULL filtergraph\n", iface); + return E_UNEXPECTED; + } + + IGraphBuilder_AddRef((IGraphBuilder *)This->mygraph); + + TRACE("(%p) return filtergraph %p\n", iface, *pfg); + return S_OK; +} + +static HRESULT WINAPI +fnCaptureGraphBuilder2_SetOutputFileName(ICaptureGraphBuilder2 * iface, + const GUID *pType, + LPCOLESTR lpstrFile, + IBaseFilter **ppf, + IFileSinkFilter **ppSink) +{ + _ICOM_THIS_From_ICaptureGraphBuilder2(CaptureGraphImpl, iface); + + FIXME("(%p/%p)->(%s, %s, %p, %p) Stub!\n", This, iface, + debugstr_guid(pType), debugstr_w(lpstrFile), ppf, ppSink); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +fnCaptureGraphBuilder2_FindInterface(ICaptureGraphBuilder2 * iface, + const GUID *pCategory, + const GUID *pType, + IBaseFilter *pf, + REFIID riid, + void **ppint) +{ + _ICOM_THIS_From_ICaptureGraphBuilder2(CaptureGraphImpl, iface); + + FIXME("(%p/%p)->(%s, %s, %p, %s, %p) - workaround stub!\n", This, iface, + debugstr_guid(pCategory), debugstr_guid(pType), + pf, debugstr_guid(riid), ppint); + + return IBaseFilter_QueryInterface(pf, riid, ppint); + /* Looks for the specified interface on the filter, upstream and + * downstream from the filter, and, optionally, only on the output + * pin of the given category. + */ +} + +static HRESULT WINAPI +fnCaptureGraphBuilder2_RenderStream(ICaptureGraphBuilder2 * iface, + const GUID *pCategory, + const GUID *pType, + IUnknown *pSource, + IBaseFilter *pfCompressor, + IBaseFilter *pfRenderer) +{ + _ICOM_THIS_From_ICaptureGraphBuilder2(CaptureGraphImpl, iface); + + FIXME("(%p/%p)->(%s, %s, %p, %p, %p) Stub!\n", This, iface, + debugstr_guid(pCategory), debugstr_guid(pType), + pSource, pfCompressor, pfRenderer); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +fnCaptureGraphBuilder2_ControlStream(ICaptureGraphBuilder2 * iface, + const GUID *pCategory, + const GUID *pType, + IBaseFilter *pFilter, + REFERENCE_TIME *pstart, + REFERENCE_TIME *pstop, + WORD wStartCookie, + WORD wStopCookie) +{ + _ICOM_THIS_From_ICaptureGraphBuilder2(CaptureGraphImpl, iface); + + FIXME("(%p/%p)->(%s, %s, %p, %p, %p, %i, %i) Stub!\n", This, iface, + debugstr_guid(pCategory), debugstr_guid(pType), + pFilter, pstart, pstop, wStartCookie, wStopCookie); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +fnCaptureGraphBuilder2_AllocCapFile(ICaptureGraphBuilder2 * iface, + LPCOLESTR lpwstr, + DWORDLONG dwlSize) +{ + _ICOM_THIS_From_ICaptureGraphBuilder2(CaptureGraphImpl, iface); + + FIXME("(%p/%p)->(%s, %lld) Stub!\n", This, iface, + debugstr_w(lpwstr), dwlSize); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +fnCaptureGraphBuilder2_CopyCaptureFile(ICaptureGraphBuilder2 * iface, + LPOLESTR lpwstrOld, + LPOLESTR lpwstrNew, + int fAllowEscAbort, + IAMCopyCaptureFileProgress *pCallback) +{ + _ICOM_THIS_From_ICaptureGraphBuilder2(CaptureGraphImpl, iface); + + FIXME("(%p/%p)->(%s, %s, %i, %p) Stub!\n", This, iface, + debugstr_w(lpwstrOld), debugstr_w(lpwstrNew), + fAllowEscAbort, pCallback); + + return E_NOTIMPL; +} + +static HRESULT WINAPI +fnCaptureGraphBuilder2_FindPin(ICaptureGraphBuilder2 * iface, + IUnknown *pSource, + PIN_DIRECTION pindir, + const GUID *pCategory, + const GUID *pType, + BOOL fUnconnected, + int num, + IPin **ppPin) +{ + _ICOM_THIS_From_ICaptureGraphBuilder2(CaptureGraphImpl, iface); + + FIXME("(%p/%p)->(%p, %x, %s, %s, %d, %i, %p) Stub!\n", This, iface, + pSource, pindir, debugstr_guid(pCategory), debugstr_guid(pType), + fUnconnected, num, ppPin); + + return E_NOTIMPL; +} + +static const ICaptureGraphBuilder2Vtbl builder2_Vtbl = +{ + fnCaptureGraphBuilder2_QueryInterface, + fnCaptureGraphBuilder2_AddRef, + fnCaptureGraphBuilder2_Release, + fnCaptureGraphBuilder2_SetFilterGraph, + fnCaptureGraphBuilder2_GetFilterGraph, + fnCaptureGraphBuilder2_SetOutputFileName, + fnCaptureGraphBuilder2_FindInterface, + fnCaptureGraphBuilder2_RenderStream, + fnCaptureGraphBuilder2_ControlStream, + fnCaptureGraphBuilder2_AllocCapFile, + fnCaptureGraphBuilder2_CopyCaptureFile, + fnCaptureGraphBuilder2_FindPin +}; + + +static HRESULT WINAPI +fnCaptureGraphBuilder_QueryInterface(ICaptureGraphBuilder * iface, + REFIID riid, LPVOID * ppv) +{ + _ICOM_THIS_From_ICaptureGraphBuilder(CaptureGraphImpl, iface); + + return IUnknown_QueryInterface(_ICaptureGraphBuilder2_(This), riid, ppv); +} + +static ULONG WINAPI +fnCaptureGraphBuilder_AddRef(ICaptureGraphBuilder * iface) +{ + _ICOM_THIS_From_ICaptureGraphBuilder(CaptureGraphImpl, iface); + + return IUnknown_AddRef(_ICaptureGraphBuilder2_(This)); +} + +static ULONG WINAPI +fnCaptureGraphBuilder_Release(ICaptureGraphBuilder * iface) +{ + _ICOM_THIS_From_ICaptureGraphBuilder(CaptureGraphImpl, iface); + + return IUnknown_Release(_ICaptureGraphBuilder2_(This)); +} + +static HRESULT WINAPI +fnCaptureGraphBuilder_SetFiltergraph(ICaptureGraphBuilder * iface, + IGraphBuilder *pfg) +{ + _ICOM_THIS_From_ICaptureGraphBuilder(CaptureGraphImpl, iface); + + return ICaptureGraphBuilder2_SetFiltergraph(_ICaptureGraphBuilder2_(This), pfg); +} + +static HRESULT WINAPI +fnCaptureGraphBuilder_GetFiltergraph(ICaptureGraphBuilder * iface, + IGraphBuilder **pfg) +{ + _ICOM_THIS_From_ICaptureGraphBuilder(CaptureGraphImpl, iface); + + return ICaptureGraphBuilder2_GetFiltergraph(_ICaptureGraphBuilder2_(This), pfg); +} + +static HRESULT WINAPI +fnCaptureGraphBuilder_SetOutputFileName(ICaptureGraphBuilder * iface, + const GUID *pType, LPCOLESTR lpstrFile, + IBaseFilter **ppf, IFileSinkFilter **ppSink) +{ + _ICOM_THIS_From_ICaptureGraphBuilder(CaptureGraphImpl, iface); + + return ICaptureGraphBuilder2_SetOutputFileName(_ICaptureGraphBuilder2_(This), + pType, lpstrFile, ppf, ppSink); +} + +static HRESULT WINAPI +fnCaptureGraphBuilder_FindInterface(ICaptureGraphBuilder * iface, + const GUID *pCategory, IBaseFilter *pf, + REFIID riid, void **ppint) +{ + _ICOM_THIS_From_ICaptureGraphBuilder(CaptureGraphImpl, iface); + + return ICaptureGraphBuilder2_FindInterface(_ICaptureGraphBuilder2_(This), + pCategory, NULL, pf, riid, ppint); +} + +static HRESULT WINAPI +fnCaptureGraphBuilder_RenderStream(ICaptureGraphBuilder * iface, + const GUID *pCategory, IUnknown *pSource, + IBaseFilter *pfCompressor, IBaseFilter *pfRenderer) +{ + _ICOM_THIS_From_ICaptureGraphBuilder(CaptureGraphImpl, iface); + + return ICaptureGraphBuilder2_RenderStream(_ICaptureGraphBuilder2_(This), + pCategory, NULL, pSource, + pfCompressor, pfRenderer); +} + +static HRESULT WINAPI +fnCaptureGraphBuilder_ControlStream(ICaptureGraphBuilder * iface, + const GUID *pCategory, IBaseFilter *pFilter, + REFERENCE_TIME *pstart, REFERENCE_TIME *pstop, + WORD wStartCookie, WORD wStopCookie) +{ + _ICOM_THIS_From_ICaptureGraphBuilder(CaptureGraphImpl, iface); + + return ICaptureGraphBuilder2_ControlStream(_ICaptureGraphBuilder2_(This), + pCategory, NULL, pFilter, pstart, + pstop, wStartCookie, wStopCookie); +} + +static HRESULT WINAPI +fnCaptureGraphBuilder_AllocCapFile(ICaptureGraphBuilder * iface, + LPCOLESTR lpstr, DWORDLONG dwlSize) +{ + _ICOM_THIS_From_ICaptureGraphBuilder(CaptureGraphImpl, iface); + + return ICaptureGraphBuilder2_AllocCapFile(_ICaptureGraphBuilder2_(This), + lpstr, dwlSize); +} + +static HRESULT WINAPI +fnCaptureGraphBuilder_CopyCaptureFile(ICaptureGraphBuilder * iface, + LPOLESTR lpwstrOld, LPOLESTR lpwstrNew, + int fAllowEscAbort, + IAMCopyCaptureFileProgress *pCallback) +{ + _ICOM_THIS_From_ICaptureGraphBuilder(CaptureGraphImpl, iface); + + return ICaptureGraphBuilder2_CopyCaptureFile(_ICaptureGraphBuilder2_(This), + lpwstrOld, lpwstrNew, + fAllowEscAbort, pCallback); +} + +static const ICaptureGraphBuilderVtbl builder_Vtbl = +{ + fnCaptureGraphBuilder_QueryInterface, + fnCaptureGraphBuilder_AddRef, + fnCaptureGraphBuilder_Release, + fnCaptureGraphBuilder_SetFiltergraph, + fnCaptureGraphBuilder_GetFiltergraph, + fnCaptureGraphBuilder_SetOutputFileName, + fnCaptureGraphBuilder_FindInterface, + fnCaptureGraphBuilder_RenderStream, + fnCaptureGraphBuilder_ControlStream, + fnCaptureGraphBuilder_AllocCapFile, + fnCaptureGraphBuilder_CopyCaptureFile +}; diff --git a/dlls/qcap/qcap_main.c b/dlls/qcap/qcap_main.c index 94a21788ccf..6fc72500791 100644 --- a/dlls/qcap/qcap_main.c +++ b/dlls/qcap/qcap_main.c @@ -119,7 +119,7 @@ static CFactoryTemplate const g_cTemplates[] = { &CLSID_FileWriter, QCAP_createFileWriter, NULL - },{ + },*/{ wCaptGraphBuilder, &CLSID_CaptureGraphBuilder, QCAP_createCaptureGraphBuilder2, @@ -129,7 +129,7 @@ static CFactoryTemplate const g_cTemplates[] = { &CLSID_CaptureGraphBuilder2, QCAP_createCaptureGraphBuilder2, NULL - },{ + }/*,{ wInfPinTeeFilter, &CLSID_InfinitePinTeeFilter, QCAP_createInfinitePinTeeFilter,