Lei Zhang : quartz: Make filtergraph aggregatable.
Alexandre Julliard
julliard at winehq.org
Fri Dec 21 07:28:33 CST 2007
Module: wine
Branch: master
Commit: 99a193ce7e661abb23b2a3ff982d8afc5eacd2ee
URL: http://source.winehq.org/git/wine.git/?a=commit;h=99a193ce7e661abb23b2a3ff982d8afc5eacd2ee
Author: Lei Zhang <thestig at google.com>
Date: Thu Dec 20 20:38:59 2007 -0800
quartz: Make filtergraph aggregatable.
---
dlls/quartz/filtergraph.c | 83 ++++++++++++++++++++++++++++++++++++++++----
dlls/quartz/tests/misc.c | 18 ++++++++++
2 files changed, 93 insertions(+), 8 deletions(-)
diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c
index fd9e8ae..fc1aa57 100644
--- a/dlls/quartz/filtergraph.c
+++ b/dlls/quartz/filtergraph.c
@@ -161,6 +161,7 @@ typedef struct _IFilterGraphImpl {
const IMediaEventSinkVtbl *IMediaEventSink_vtbl;
const IGraphConfigVtbl *IGraphConfig_vtbl;
const IMediaPositionVtbl *IMediaPosition_vtbl;
+ const IUnknownVtbl * IInner_vtbl;
/* IAMGraphStreams */
/* IAMStats */
/* IBasicVideo2 */
@@ -194,16 +195,29 @@ typedef struct _IFilterGraphImpl {
CRITICAL_SECTION cs;
ITF_CACHE_ENTRY ItfCacheEntries[MAX_ITF_CACHE_ENTRIES];
int nItfCacheEntries;
+ IUnknown * pUnkOuter;
+ BOOL bUnkOuterValid;
+ BOOL bAggregatable;
} IFilterGraphImpl;
+static HRESULT WINAPI Filtergraph_QueryInterface(IFilterGraphImpl *This,
+ REFIID riid, LPVOID * ppv);
+static ULONG WINAPI Filtergraph_AddRef(IFilterGraphImpl *This);
+static ULONG WINAPI Filtergraph_Release(IFilterGraphImpl *This);
-static HRESULT Filtergraph_QueryInterface(IFilterGraphImpl *This,
+static HRESULT WINAPI FilterGraphInner_QueryInterface(IUnknown * iface,
REFIID riid,
LPVOID *ppvObj) {
+ ICOM_THIS_MULTI(IFilterGraphImpl, IInner_vtbl, iface);
TRACE("(%p)->(%s (%p), %p)\n", This, debugstr_guid(riid), riid, ppvObj);
- if (IsEqualGUID(&IID_IUnknown, riid) ||
- IsEqualGUID(&IID_IFilterGraph, riid) ||
+ if (This->bAggregatable)
+ This->bUnkOuterValid = TRUE;
+
+ if (IsEqualGUID(&IID_IUnknown, riid)) {
+ *ppvObj = &(This->IInner_vtbl);
+ TRACE(" returning IUnknown interface (%p)\n", *ppvObj);
+ } else if (IsEqualGUID(&IID_IFilterGraph, riid) ||
IsEqualGUID(&IID_IFilterGraph2, riid) ||
IsEqualGUID(&IID_IGraphBuilder, riid)) {
*ppvObj = &(This->IFilterGraph2_vtbl);
@@ -246,11 +260,12 @@ static HRESULT Filtergraph_QueryInterface(IFilterGraphImpl *This,
return E_NOINTERFACE;
}
- InterlockedIncrement(&This->ref);
+ IUnknown_AddRef((IUnknown *)(*ppvObj));
return S_OK;
}
-static ULONG Filtergraph_AddRef(IFilterGraphImpl *This) {
+static ULONG WINAPI FilterGraphInner_AddRef(IUnknown * iface) {
+ ICOM_THIS_MULTI(IFilterGraphImpl, IInner_vtbl, iface);
ULONG ref = InterlockedIncrement(&This->ref);
TRACE("(%p)->(): new ref = %d\n", This, ref);
@@ -258,7 +273,8 @@ static ULONG Filtergraph_AddRef(IFilterGraphImpl *This) {
return ref;
}
-static ULONG Filtergraph_Release(IFilterGraphImpl *This) {
+static ULONG WINAPI FilterGraphInner_Release(IUnknown * iface) {
+ ICOM_THIS_MULTI(IFilterGraphImpl, IInner_vtbl, iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p)->(): new ref = %d\n", This, ref);
@@ -4618,6 +4634,54 @@ static const IGraphConfigVtbl IGraphConfig_VTable =
GraphConfig_RemoveFilterEx
};
+static const IUnknownVtbl IInner_VTable =
+{
+ FilterGraphInner_QueryInterface,
+ FilterGraphInner_AddRef,
+ FilterGraphInner_Release
+};
+
+static HRESULT WINAPI Filtergraph_QueryInterface(IFilterGraphImpl *This,
+ REFIID riid,
+ LPVOID * ppv) {
+ 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 Filtergraph_AddRef(IFilterGraphImpl *This) {
+ if (This->pUnkOuter && This->bUnkOuterValid)
+ return IUnknown_AddRef(This->pUnkOuter);
+ return IUnknown_AddRef((IUnknown *)&(This->IInner_vtbl));
+}
+
+static ULONG WINAPI Filtergraph_Release(IFilterGraphImpl *This) {
+ if (This->pUnkOuter && This->bUnkOuterValid)
+ return IUnknown_Release(This->pUnkOuter);
+ return IUnknown_Release((IUnknown *)&(This->IInner_vtbl));
+}
+
/* This is the only function that actually creates a FilterGraph class... */
HRESULT FilterGraph_create(IUnknown *pUnkOuter, LPVOID *ppObj)
{
@@ -4626,10 +4690,13 @@ HRESULT FilterGraph_create(IUnknown *pUnkOuter, LPVOID *ppObj)
TRACE("(%p,%p)\n", pUnkOuter, ppObj);
- if( pUnkOuter )
- return CLASS_E_NOAGGREGATION;
+ *ppObj = NULL;
fimpl = CoTaskMemAlloc(sizeof(*fimpl));
+ fimpl->pUnkOuter = pUnkOuter;
+ fimpl->bUnkOuterValid = FALSE;
+ fimpl->bAggregatable = FALSE;
+ fimpl->IInner_vtbl = &IInner_VTable;
fimpl->IFilterGraph2_vtbl = &IFilterGraph2_VTable;
fimpl->IMediaControl_vtbl = &IMediaControl_VTable;
fimpl->IMediaSeeking_vtbl = &IMediaSeeking_VTable;
diff --git a/dlls/quartz/tests/misc.c b/dlls/quartz/tests/misc.c
index 44994cd..fbe81bf 100644
--- a/dlls/quartz/tests/misc.c
+++ b/dlls/quartz/tests/misc.c
@@ -150,9 +150,27 @@ static void test_video_renderer_aggregations(void)
}
}
+static void test_filter_graph_aggregations(void)
+{
+ IID iids[] = {
+ IID_IFilterGraph2, IID_IMediaControl, IID_IGraphBuilder,
+ IID_IFilterGraph, IID_IMediaSeeking, IID_IBasicAudio, IID_IBasicVideo,
+ IID_IVideoWindow, IID_IMediaEventEx, IID_IMediaFilter,
+ IID_IMediaEventSink, IID_IGraphConfig, IID_IMediaPosition
+ };
+ int i;
+
+ for (i = 0; i < sizeof(iids) / sizeof(iids[0]); i++)
+ {
+ test_aggregation(CLSID_SystemClock, CLSID_FilterGraph,
+ IID_IReferenceClock, iids[i]);
+ }
+}
+
START_TEST(misc)
{
CoInitialize(NULL);
test_video_renderer_aggregations();
+ test_filter_graph_aggregations();
}
More information about the wine-cvs
mailing list