From 932cc2d7f910ec9a7df17384610832922e67b861 Mon Sep 17 00:00:00 2001 From: Lei Zhang Date: Thu, 13 Dec 2007 03:16:27 -0800 Subject: [PATCH] quartz: Make video renderer aggregatable. --- dlls/quartz/tests/videorenderer.c | 4 -- dlls/quartz/videorenderer.c | 84 ++++++++++++++++++++++++++++++++++----- 2 files changed, 74 insertions(+), 14 deletions(-) diff --git a/dlls/quartz/tests/videorenderer.c b/dlls/quartz/tests/videorenderer.c index ce0a43fc908..3c157721381 100644 --- a/dlls/quartz/tests/videorenderer.c +++ b/dlls/quartz/tests/videorenderer.c @@ -69,18 +69,14 @@ static void test_aggregation(void) /* for aggregation, we should only be able to request IUnknown */ hr = CoCreateInstance(&CLSID_VideoRenderer, pUnkOuter, CLSCTX_INPROC_SERVER, &IID_IVideoWindow, (LPVOID*)&pVideoWindowInner); - todo_wine { ok(hr == E_NOINTERFACE, "CoCreateInstance returned %x\n", hr); - } ok(pVideoWindowInner == NULL, "pVideoWindowInner is not NULL\n"); /* aggregation, request IUnknown */ hr = CoCreateInstance(&CLSID_VideoRenderer, pUnkOuter, CLSCTX_INPROC_SERVER, &IID_IUnknown, (LPVOID*)&pUnkInner); - todo_wine { ok(hr == S_OK, "CoCreateInstance returned %x\n", hr); ok(pUnkInner != NULL, "pUnkInner is NULL\n"); - } if (!pUnkInner) { diff --git a/dlls/quartz/videorenderer.c b/dlls/quartz/videorenderer.c index 67e601ebb42..1a4594c7475 100644 --- a/dlls/quartz/videorenderer.c +++ b/dlls/quartz/videorenderer.c @@ -46,6 +46,7 @@ static BOOL wnd_class_registered = FALSE; static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0}; static const IBaseFilterVtbl VideoRenderer_Vtbl; +static const IUnknownVtbl IInner_VTable; static const IBasicVideoVtbl IBasicVideo_VTable; static const IVideoWindowVtbl IVideoWindow_VTable; static const IPinVtbl VideoRenderer_InputPin_Vtbl; @@ -55,6 +56,7 @@ typedef struct VideoRendererImpl const IBaseFilterVtbl * lpVtbl; const IBasicVideoVtbl * IBasicVideo_vtbl; const IVideoWindowVtbl * IVideoWindow_vtbl; + const IUnknownVtbl * IInner_vtbl; LONG refCount; CRITICAL_SECTION csFilter; @@ -79,6 +81,9 @@ typedef struct VideoRendererImpl RECT WindowPos; long VideoWidth; long VideoHeight; + IUnknown * pUnkOuter; + BOOL bUnkOuterValid; + BOOL bAggregatable; } VideoRendererImpl; static LRESULT CALLBACK VideoWndProcA(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) @@ -436,10 +441,11 @@ HRESULT VideoRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv) *ppv = NULL; - if (pUnkOuter) - return CLASS_E_NOAGGREGATION; - pVideoRenderer = CoTaskMemAlloc(sizeof(VideoRendererImpl)); + pVideoRenderer->pUnkOuter = pUnkOuter; + pVideoRenderer->bUnkOuterValid = FALSE; + pVideoRenderer->bAggregatable = FALSE; + pVideoRenderer->IInner_vtbl = &IInner_VTable; pVideoRenderer->lpVtbl = &VideoRenderer_Vtbl; pVideoRenderer->IBasicVideo_vtbl = &IBasicVideo_VTable; @@ -482,15 +488,18 @@ HRESULT VideoRenderer_create(IUnknown * pUnkOuter, LPVOID * ppv) return hr; } -static HRESULT WINAPI VideoRenderer_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv) +static HRESULT WINAPI Inner_QueryInterface(IUnknown * iface, REFIID riid, LPVOID * ppv) { - VideoRendererImpl *This = (VideoRendererImpl *)iface; + ICOM_THIS_MULTI(VideoRendererImpl, IInner_vtbl, iface); TRACE("(%p/%p)->(%s, %p)\n", This, iface, qzdebugstr_guid(riid), ppv); + if (This->bAggregatable) + This->bUnkOuterValid = TRUE; + *ppv = NULL; if (IsEqualIID(riid, &IID_IUnknown)) - *ppv = (LPVOID)This; + *ppv = (LPVOID)&(This->IInner_vtbl); else if (IsEqualIID(riid, &IID_IPersist)) *ppv = (LPVOID)This; else if (IsEqualIID(riid, &IID_IMediaFilter)) @@ -513,9 +522,9 @@ static HRESULT WINAPI VideoRenderer_QueryInterface(IBaseFilter * iface, REFIID r return E_NOINTERFACE; } -static ULONG WINAPI VideoRenderer_AddRef(IBaseFilter * iface) +static ULONG WINAPI Inner_AddRef(IUnknown * iface) { - VideoRendererImpl *This = (VideoRendererImpl *)iface; + ICOM_THIS_MULTI(VideoRendererImpl, IInner_vtbl, iface); ULONG refCount = InterlockedIncrement(&This->refCount); TRACE("(%p/%p)->() AddRef from %d\n", This, iface, refCount - 1); @@ -523,9 +532,9 @@ static ULONG WINAPI VideoRenderer_AddRef(IBaseFilter * iface) return refCount; } -static ULONG WINAPI VideoRenderer_Release(IBaseFilter * iface) +static ULONG WINAPI Inner_Release(IUnknown * iface) { - VideoRendererImpl *This = (VideoRendererImpl *)iface; + ICOM_THIS_MULTI(VideoRendererImpl, IInner_vtbl, iface); ULONG refCount = InterlockedDecrement(&This->refCount); TRACE("(%p/%p)->() Release from %d\n", This, iface, refCount + 1); @@ -566,6 +575,61 @@ static ULONG WINAPI VideoRenderer_Release(IBaseFilter * iface) return refCount; } +static const IUnknownVtbl IInner_VTable = +{ + Inner_QueryInterface, + Inner_AddRef, + Inner_Release +}; + +static HRESULT WINAPI VideoRenderer_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv) +{ + VideoRendererImpl *This = (VideoRendererImpl *)iface; + + if (This->bAggregatable) + This->bUnkOuterValid = TRUE; + + if (This->pUnkOuter) + { + if (This->bAggregatable) + return IUnknown_QueryInterface(This->pUnkOuter, riid, ppv); + + if (IsEqualIID(riid, &IID_IUnknown)) + { + HRESULT hr; + + IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl)); + hr = IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv); + IUnknown_Release((IUnknown *)&(This->IInner_vtbl)); + This->bAggregatable = TRUE; + return hr; + } + + *ppv = NULL; + return E_NOINTERFACE; + } + + return IUnknown_QueryInterface((IUnknown *)&(This->IInner_vtbl), riid, ppv); +} + +static ULONG WINAPI VideoRenderer_AddRef(IBaseFilter * iface) +{ + VideoRendererImpl *This = (VideoRendererImpl *)iface; + + if (This->pUnkOuter && This->bUnkOuterValid) + return IUnknown_AddRef(This->pUnkOuter); + return IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl)); +} + +static ULONG WINAPI VideoRenderer_Release(IBaseFilter * iface) +{ + VideoRendererImpl *This = (VideoRendererImpl *)iface; + + if (This->pUnkOuter && This->bUnkOuterValid) + return IUnknown_Release(This->pUnkOuter); + return IUnknown_Release((IUnknown *)&(This->IInner_vtbl)); +} + /** IPersist methods **/ static HRESULT WINAPI VideoRenderer_GetClassID(IBaseFilter * iface, CLSID * pClsid) -- 2.11.4.GIT