quartz: Make filtergraph aggregatable.
This commit is contained in:
parent
5ddb13381e
commit
99a193ce7e
|
@ -161,6 +161,7 @@ typedef struct _IFilterGraphImpl {
|
||||||
const IMediaEventSinkVtbl *IMediaEventSink_vtbl;
|
const IMediaEventSinkVtbl *IMediaEventSink_vtbl;
|
||||||
const IGraphConfigVtbl *IGraphConfig_vtbl;
|
const IGraphConfigVtbl *IGraphConfig_vtbl;
|
||||||
const IMediaPositionVtbl *IMediaPosition_vtbl;
|
const IMediaPositionVtbl *IMediaPosition_vtbl;
|
||||||
|
const IUnknownVtbl * IInner_vtbl;
|
||||||
/* IAMGraphStreams */
|
/* IAMGraphStreams */
|
||||||
/* IAMStats */
|
/* IAMStats */
|
||||||
/* IBasicVideo2 */
|
/* IBasicVideo2 */
|
||||||
|
@ -194,16 +195,29 @@ typedef struct _IFilterGraphImpl {
|
||||||
CRITICAL_SECTION cs;
|
CRITICAL_SECTION cs;
|
||||||
ITF_CACHE_ENTRY ItfCacheEntries[MAX_ITF_CACHE_ENTRIES];
|
ITF_CACHE_ENTRY ItfCacheEntries[MAX_ITF_CACHE_ENTRIES];
|
||||||
int nItfCacheEntries;
|
int nItfCacheEntries;
|
||||||
|
IUnknown * pUnkOuter;
|
||||||
|
BOOL bUnkOuterValid;
|
||||||
|
BOOL bAggregatable;
|
||||||
} IFilterGraphImpl;
|
} 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,
|
REFIID riid,
|
||||||
LPVOID *ppvObj) {
|
LPVOID *ppvObj) {
|
||||||
|
ICOM_THIS_MULTI(IFilterGraphImpl, IInner_vtbl, iface);
|
||||||
TRACE("(%p)->(%s (%p), %p)\n", This, debugstr_guid(riid), riid, ppvObj);
|
TRACE("(%p)->(%s (%p), %p)\n", This, debugstr_guid(riid), riid, ppvObj);
|
||||||
|
|
||||||
if (IsEqualGUID(&IID_IUnknown, riid) ||
|
if (This->bAggregatable)
|
||||||
IsEqualGUID(&IID_IFilterGraph, riid) ||
|
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_IFilterGraph2, riid) ||
|
||||||
IsEqualGUID(&IID_IGraphBuilder, riid)) {
|
IsEqualGUID(&IID_IGraphBuilder, riid)) {
|
||||||
*ppvObj = &(This->IFilterGraph2_vtbl);
|
*ppvObj = &(This->IFilterGraph2_vtbl);
|
||||||
|
@ -246,11 +260,12 @@ static HRESULT Filtergraph_QueryInterface(IFilterGraphImpl *This,
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
InterlockedIncrement(&This->ref);
|
IUnknown_AddRef((IUnknown *)(*ppvObj));
|
||||||
return S_OK;
|
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);
|
ULONG ref = InterlockedIncrement(&This->ref);
|
||||||
|
|
||||||
TRACE("(%p)->(): new ref = %d\n", This, ref);
|
TRACE("(%p)->(): new ref = %d\n", This, ref);
|
||||||
|
@ -258,7 +273,8 @@ static ULONG Filtergraph_AddRef(IFilterGraphImpl *This) {
|
||||||
return ref;
|
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);
|
ULONG ref = InterlockedDecrement(&This->ref);
|
||||||
|
|
||||||
TRACE("(%p)->(): new ref = %d\n", This, ref);
|
TRACE("(%p)->(): new ref = %d\n", This, ref);
|
||||||
|
@ -4618,6 +4634,54 @@ static const IGraphConfigVtbl IGraphConfig_VTable =
|
||||||
GraphConfig_RemoveFilterEx
|
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... */
|
/* This is the only function that actually creates a FilterGraph class... */
|
||||||
HRESULT FilterGraph_create(IUnknown *pUnkOuter, LPVOID *ppObj)
|
HRESULT FilterGraph_create(IUnknown *pUnkOuter, LPVOID *ppObj)
|
||||||
{
|
{
|
||||||
|
@ -4626,10 +4690,13 @@ HRESULT FilterGraph_create(IUnknown *pUnkOuter, LPVOID *ppObj)
|
||||||
|
|
||||||
TRACE("(%p,%p)\n", pUnkOuter, ppObj);
|
TRACE("(%p,%p)\n", pUnkOuter, ppObj);
|
||||||
|
|
||||||
if( pUnkOuter )
|
*ppObj = NULL;
|
||||||
return CLASS_E_NOAGGREGATION;
|
|
||||||
|
|
||||||
fimpl = CoTaskMemAlloc(sizeof(*fimpl));
|
fimpl = CoTaskMemAlloc(sizeof(*fimpl));
|
||||||
|
fimpl->pUnkOuter = pUnkOuter;
|
||||||
|
fimpl->bUnkOuterValid = FALSE;
|
||||||
|
fimpl->bAggregatable = FALSE;
|
||||||
|
fimpl->IInner_vtbl = &IInner_VTable;
|
||||||
fimpl->IFilterGraph2_vtbl = &IFilterGraph2_VTable;
|
fimpl->IFilterGraph2_vtbl = &IFilterGraph2_VTable;
|
||||||
fimpl->IMediaControl_vtbl = &IMediaControl_VTable;
|
fimpl->IMediaControl_vtbl = &IMediaControl_VTable;
|
||||||
fimpl->IMediaSeeking_vtbl = &IMediaSeeking_VTable;
|
fimpl->IMediaSeeking_vtbl = &IMediaSeeking_VTable;
|
||||||
|
|
|
@ -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)
|
START_TEST(misc)
|
||||||
{
|
{
|
||||||
CoInitialize(NULL);
|
CoInitialize(NULL);
|
||||||
|
|
||||||
test_video_renderer_aggregations();
|
test_video_renderer_aggregations();
|
||||||
|
test_filter_graph_aggregations();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue