Lei Zhang : quartz: Make video renderer aggregatable.
Alexandre Julliard
julliard at winehq.org
Thu Dec 13 08:23:16 CST 2007
Module: wine
Branch: master
Commit: 932cc2d7f910ec9a7df17384610832922e67b861
URL: http://source.winehq.org/git/wine.git/?a=commit;h=932cc2d7f910ec9a7df17384610832922e67b861
Author: Lei Zhang <thestig at google.com>
Date: Thu Dec 13 03:16:27 2007 -0800
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 ce0a43f..3c15772 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 67e601e..1a4594c 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)
More information about the wine-cvs
mailing list