diff --git a/dlls/qcap/Makefile.in b/dlls/qcap/Makefile.in index ebb432d32e0..41871e359c3 100644 --- a/dlls/qcap/Makefile.in +++ b/dlls/qcap/Makefile.in @@ -2,6 +2,7 @@ MODULE = qcap.dll IMPORTS = strmiids strmbase uuid ole32 gdi32 advapi32 C_SRCS = \ + avico.c \ avimux.c \ capturegraph.c \ enummedia.c \ diff --git a/dlls/qcap/avico.c b/dlls/qcap/avico.c new file mode 100644 index 00000000000..a24a1c3aecf --- /dev/null +++ b/dlls/qcap/avico.c @@ -0,0 +1,184 @@ +/* + * Copyright 2013 Jacek Caban for CodeWeavers + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "dshow.h" + +#include "qcap_main.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(qcap); + +typedef struct { + BaseFilter filter; +} AVICompressor; + +static inline AVICompressor *impl_from_BaseFilter(BaseFilter *filter) +{ + return CONTAINING_RECORD(filter, AVICompressor, filter); +} + +static inline AVICompressor *impl_from_IBaseFilter(IBaseFilter *iface) +{ + BaseFilter *filter = CONTAINING_RECORD(iface, BaseFilter, IBaseFilter_iface); + return impl_from_BaseFilter(filter); +} + +static HRESULT WINAPI AVICompressor_QueryInterface(IBaseFilter *iface, REFIID riid, void **ppv) +{ + AVICompressor *This = impl_from_IBaseFilter(iface); + + if(IsEqualIID(riid, &IID_IUnknown)) { + TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv); + *ppv = &This->filter.IBaseFilter_iface; + }else if(IsEqualIID(riid, &IID_IPersist)) { + TRACE("(%p)->(IID_IPersist %p)\n", This, ppv); + *ppv = &This->filter.IBaseFilter_iface; + }else if(IsEqualIID(riid, &IID_IMediaFilter)) { + TRACE("(%p)->(IID_IMediaFilter %p)\n", This, ppv); + *ppv = &This->filter.IBaseFilter_iface; + }else if(IsEqualIID(riid, &IID_IBaseFilter)) { + TRACE("(%p)->(IID_IBaseFilter %p)\n", This, ppv); + *ppv = &This->filter.IBaseFilter_iface; + }else { + FIXME("no interface for %s\n", debugstr_guid(riid)); + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; + +} + +static ULONG WINAPI AVICompressor_Release(IBaseFilter *iface) +{ + AVICompressor *This = impl_from_IBaseFilter(iface); + ULONG ref = BaseFilterImpl_Release(&This->filter.IBaseFilter_iface); + + TRACE("(%p) ref=%d\n", This, ref); + + if(!ref) + heap_free(This); + + return ref; +} + +static HRESULT WINAPI AVICompressor_Stop(IBaseFilter *iface) +{ + AVICompressor *This = impl_from_IBaseFilter(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI AVICompressor_Pause(IBaseFilter *iface) +{ + AVICompressor *This = impl_from_IBaseFilter(iface); + FIXME("(%p)\n", This); + return E_NOTIMPL; +} + +static HRESULT WINAPI AVICompressor_Run(IBaseFilter *iface, REFERENCE_TIME tStart) +{ + AVICompressor *This = impl_from_IBaseFilter(iface); + FIXME("(%p)->(%s)\n", This, wine_dbgstr_longlong(tStart)); + return E_NOTIMPL; +} + +static HRESULT WINAPI AVICompressor_FindPin(IBaseFilter *iface, LPCWSTR Id, IPin **ppPin) +{ + AVICompressor *This = impl_from_IBaseFilter(iface); + FIXME("(%p)->(%s %p)\n", This, debugstr_w(Id), ppPin); + return VFW_E_NOT_FOUND; +} + +static HRESULT WINAPI AVICompressor_QueryFilterInfo(IBaseFilter *iface, FILTER_INFO *pInfo) +{ + AVICompressor *This = impl_from_IBaseFilter(iface); + FIXME("(%p)->(%p)\n", This, pInfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI AVICompressor_QueryVendorInfo(IBaseFilter *iface, LPWSTR *pVendorInfo) +{ + AVICompressor *This = impl_from_IBaseFilter(iface); + FIXME("(%p)->(%p)\n", This, pVendorInfo); + return E_NOTIMPL; +} + +static const IBaseFilterVtbl AVICompressorVtbl = { + AVICompressor_QueryInterface, + BaseFilterImpl_AddRef, + AVICompressor_Release, + BaseFilterImpl_GetClassID, + AVICompressor_Stop, + AVICompressor_Pause, + AVICompressor_Run, + BaseFilterImpl_GetState, + BaseFilterImpl_SetSyncSource, + BaseFilterImpl_GetSyncSource, + BaseFilterImpl_EnumPins, + AVICompressor_FindPin, + AVICompressor_QueryFilterInfo, + BaseFilterImpl_JoinFilterGraph, + AVICompressor_QueryVendorInfo +}; + +static IPin* WINAPI AVICompressor_GetPin(BaseFilter *iface, int pos) +{ + AVICompressor *This = impl_from_BaseFilter(iface); + FIXME("(%p)->(%d)\n", This, pos); + return NULL; +} + +static LONG WINAPI AVICompressor_GetPinCount(BaseFilter *iface) +{ + AVICompressor *This = impl_from_BaseFilter(iface); + FIXME("(%p)\n", This); + return 0; +} + +static const BaseFilterFuncTable filter_func_table = { + AVICompressor_GetPin, + AVICompressor_GetPinCount +}; + +IUnknown* WINAPI QCAP_createAVICompressor(IUnknown *outer, HRESULT *phr) +{ + AVICompressor *compressor; + + TRACE("\n"); + + compressor = heap_alloc_zero(sizeof(*compressor)); + if(!compressor) { + *phr = E_NOINTERFACE; + return NULL; + } + + BaseFilter_Init(&compressor->filter, &AVICompressorVtbl, &CLSID_AVICo, + (DWORD_PTR)(__FILE__ ": AVICompressor.csFilter"), &filter_func_table); + + *phr = S_OK; + return (IUnknown*)&compressor->filter.IBaseFilter_iface; +} diff --git a/dlls/qcap/qcap_main.c b/dlls/qcap/qcap_main.c index e0cd43d6141..0f9ed14881d 100644 --- a/dlls/qcap/qcap_main.c +++ b/dlls/qcap/qcap_main.c @@ -84,7 +84,7 @@ FactoryTemplate const g_Templates[] = { },{ wAVICompressor, &CLSID_AVICo, - NULL, /* FIXME: Implement QCAP_createAVICompressor */ + QCAP_createAVICompressor, NULL },{ wVFWCaptFilter, diff --git a/dlls/qcap/qcap_main.h b/dlls/qcap/qcap_main.h index 15449a37e8d..f4684c1dd50 100644 --- a/dlls/qcap/qcap_main.h +++ b/dlls/qcap/qcap_main.h @@ -28,6 +28,7 @@ extern IUnknown * WINAPI QCAP_createAudioCaptureFilter(IUnknown *pUnkOuter, HRES extern IUnknown * WINAPI QCAP_createAVICompressor(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN; extern IUnknown * WINAPI QCAP_createVFWCaptureFilter(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN; extern IUnknown * WINAPI QCAP_createVFWCaptureFilterPropertyPage(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN; +extern IUnknown * WINAPI QCAP_createAVICompressor(IUnknown*,HRESULT*) DECLSPEC_HIDDEN; extern IUnknown * WINAPI QCAP_createAVIMux(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN; extern IUnknown * WINAPI QCAP_createAVIMuxPropertyPage(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN; extern IUnknown * WINAPI QCAP_createAVIMuxPropertyPage1(IUnknown *pUnkOuter, HRESULT *phr) DECLSPEC_HIDDEN; @@ -58,4 +59,19 @@ enum YUV_Format { void YUV_Init(void) DECLSPEC_HIDDEN; void YUV_To_RGB24(enum YUV_Format format, unsigned char *target, const unsigned char *source, int width, int height) DECLSPEC_HIDDEN; +static inline void * __WINE_ALLOC_SIZE(1) heap_alloc(size_t len) +{ + return HeapAlloc(GetProcessHeap(), 0, len); +} + +static inline void * __WINE_ALLOC_SIZE(1) heap_alloc_zero(size_t len) +{ + return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, len); +} + +static inline BOOL heap_free(void *mem) +{ + return HeapFree(GetProcessHeap(), 0, mem); +} + #endif /* _QCAP_MAIN_H_DEFINED */ diff --git a/dlls/qcap/tests/qcap.c b/dlls/qcap/tests/qcap.c index 86beda7ae3c..014a7636682 100644 --- a/dlls/qcap/tests/qcap.c +++ b/dlls/qcap/tests/qcap.c @@ -1333,6 +1333,21 @@ static void test_AviMux(void) IBaseFilter_Release(avimux); } +static void test_AviCo(void) +{ + IBaseFilter *avico; + HRESULT hres; + + hres = CoCreateInstance(&CLSID_AVICo, NULL, CLSCTX_INPROC_SERVER, &IID_IBaseFilter, (void**)&avico); + if(hres == REGDB_E_CLASSNOTREG) { + win_skip("CLSID_AVICo not restered\n"); + return; + } + ok(hres == S_OK, "Could not create CLSID_AVICo class: %08x\n", hres); + + IBaseFilter_Release(avico); +} + START_TEST(qcap) { if (SUCCEEDED(CoInitialize(NULL))) @@ -1341,6 +1356,8 @@ START_TEST(qcap) test_CaptureGraphBuilder_RenderStream(); test_AviMux_QueryInterface(); test_AviMux(); + test_AviCo(); + CoUninitialize(); } else