Commit 73676850 authored by Michael Stefaniuc's avatar Michael Stefaniuc Committed by Alexandre Julliard

qedit: Support COM aggregation for SampleGrabber.

parent 703d0a33
...@@ -105,6 +105,9 @@ static HRESULT WINAPI DSCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter ...@@ -105,6 +105,9 @@ static HRESULT WINAPI DSCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter
TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj); TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
*ppobj = NULL; *ppobj = NULL;
if (pOuter && !IsEqualGUID(&IID_IUnknown, riid))
return E_INVALIDARG;
hres = This->pfnCreateInstance(pOuter, (LPVOID *) &punk); hres = This->pfnCreateInstance(pOuter, (LPVOID *) &punk);
if (SUCCEEDED(hres)) { if (SUCCEEDED(hres)) {
hres = IUnknown_QueryInterface(punk, riid, ppobj); hres = IUnknown_QueryInterface(punk, riid, ppobj);
......
...@@ -365,11 +365,13 @@ static inline SG_Pin *impl_from_IPin(IPin *iface) ...@@ -365,11 +365,13 @@ static inline SG_Pin *impl_from_IPin(IPin *iface)
/* Sample Grabber filter implementation */ /* Sample Grabber filter implementation */
typedef struct _SG_Impl { typedef struct _SG_Impl {
IUnknown IUnknown_inner;
IBaseFilter IBaseFilter_iface; IBaseFilter IBaseFilter_iface;
ISampleGrabber ISampleGrabber_iface; ISampleGrabber ISampleGrabber_iface;
IMemInputPin IMemInputPin_iface; IMemInputPin IMemInputPin_iface;
/* TODO: IMediaPosition, IMediaSeeking, IQualityControl */ /* TODO: IMediaPosition, IMediaSeeking, IQualityControl */
LONG refCount; IUnknown *outer_unk;
LONG ref;
CRITICAL_SECTION critSect; CRITICAL_SECTION critSect;
FILTER_INFO info; FILTER_INFO info;
FILTER_STATE state; FILTER_STATE state;
...@@ -392,7 +394,11 @@ enum { ...@@ -392,7 +394,11 @@ enum {
OneShot_Past, OneShot_Past,
}; };
/* Get the SampleGrabber implementation This pointer from various interface pointers */ static inline SG_Impl *impl_from_IUnknown(IUnknown *iface)
{
return CONTAINING_RECORD(iface, SG_Impl, IUnknown_inner);
}
static inline SG_Impl *impl_from_IBaseFilter(IBaseFilter *iface) static inline SG_Impl *impl_from_IBaseFilter(IBaseFilter *iface)
{ {
return CONTAINING_RECORD(iface, SG_Impl, IBaseFilter_iface); return CONTAINING_RECORD(iface, SG_Impl, IBaseFilter_iface);
...@@ -431,61 +437,71 @@ static void SampleGrabber_cleanup(SG_Impl *This) ...@@ -431,61 +437,71 @@ static void SampleGrabber_cleanup(SG_Impl *This)
DeleteCriticalSection(&This->critSect); DeleteCriticalSection(&This->critSect);
} }
/* Common helper AddRef called from all interfaces */ /* SampleGrabber inner IUnknown */
static ULONG SampleGrabber_addref(SG_Impl *This) static HRESULT WINAPI SampleGrabber_QueryInterface(IUnknown *iface, REFIID riid, void **ppv)
{ {
ULONG refCount = InterlockedIncrement(&This->refCount); SG_Impl *This = impl_from_IUnknown(iface);
TRACE("(%p) new ref = %u\n", This, refCount);
return refCount; TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
*ppv = NULL;
if (IsEqualIID(riid, &IID_IUnknown))
*ppv = &This->IUnknown_inner;
else if (IsEqualIID(riid, &IID_IPersist) || IsEqualIID(riid, &IID_IMediaFilter) ||
IsEqualIID(riid, &IID_IBaseFilter))
*ppv = &This->IBaseFilter_iface;
else if (IsEqualIID(riid, &IID_ISampleGrabber))
*ppv = &This->ISampleGrabber_iface;
else if (IsEqualIID(riid, &IID_IMemInputPin))
*ppv = &This->IMemInputPin_iface;
else if (IsEqualIID(riid, &IID_IMediaPosition))
FIXME("IMediaPosition not implemented\n");
else if (IsEqualIID(riid, &IID_IMediaSeeking))
FIXME("IMediaSeeking not implemented\n");
else if (IsEqualIID(riid, &IID_IQualityControl))
FIXME("IQualityControl not implemented\n");
else
WARN("(%p, %s,%p): not found\n", This, debugstr_guid(riid), ppv);
if (!*ppv)
return E_NOINTERFACE;
IUnknown_AddRef((IUnknown*)*ppv);
return S_OK;
} }
/* Common helper Release called from all interfaces */ static ULONG WINAPI SampleGrabber_AddRef(IUnknown *iface)
static ULONG SampleGrabber_release(SG_Impl *This)
{ {
ULONG refCount = InterlockedDecrement(&This->refCount); SG_Impl *This = impl_from_IUnknown(iface);
TRACE("(%p) new ref = %u\n", This, refCount); ULONG ref = InterlockedIncrement(&This->ref);
if (refCount == 0)
TRACE("(%p) new ref = %u\n", This, ref);
return ref;
}
static ULONG WINAPI SampleGrabber_Release(IUnknown *iface)
{
SG_Impl *This = impl_from_IUnknown(iface);
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p) new ref = %u\n", This, ref);
if (ref == 0)
{ {
SampleGrabber_cleanup(This); SampleGrabber_cleanup(This);
CoTaskMemFree(This); CoTaskMemFree(This);
return 0; return 0;
} }
return refCount; return ref;
} }
/* Common helper QueryInterface called from all interfaces */ static const IUnknownVtbl samplegrabber_vtbl =
static HRESULT SampleGrabber_query(SG_Impl *This, REFIID riid, void **ppvObject)
{ {
TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject); SampleGrabber_QueryInterface,
SampleGrabber_AddRef,
if (IsEqualIID(riid, &IID_IUnknown) || SampleGrabber_Release,
IsEqualIID(riid, &IID_IPersist) || };
IsEqualIID(riid, &IID_IMediaFilter) ||
IsEqualIID(riid, &IID_IBaseFilter)) {
SampleGrabber_addref(This);
*ppvObject = &This->IBaseFilter_iface;
return S_OK;
}
else if (IsEqualIID(riid, &IID_ISampleGrabber)) {
SampleGrabber_addref(This);
*ppvObject = &This->ISampleGrabber_iface;
return S_OK;
}
else if (IsEqualIID(riid, &IID_IMemInputPin)) {
SampleGrabber_addref(This);
*ppvObject = &This->IMemInputPin_iface;
return S_OK;
}
else if (IsEqualIID(riid, &IID_IMediaPosition))
FIXME("IMediaPosition not implemented\n");
else if (IsEqualIID(riid, &IID_IMediaSeeking))
FIXME("IMediaSeeking not implemented\n");
else if (IsEqualIID(riid, &IID_IQualityControl))
FIXME("IQualityControl not implemented\n");
*ppvObject = NULL;
WARN("(%p, %s,%p): not found\n", This, debugstr_guid(riid), ppvObject);
return E_NOINTERFACE;
}
/* Helper that buffers data and/or calls installed sample callbacks */ /* Helper that buffers data and/or calls installed sample callbacks */
static void SampleGrabber_callback(SG_Impl *This, IMediaSample *sample) static void SampleGrabber_callback(SG_Impl *This, IMediaSample *sample)
...@@ -554,7 +570,7 @@ static HRESULT WINAPI ...@@ -554,7 +570,7 @@ static HRESULT WINAPI
SampleGrabber_IBaseFilter_QueryInterface(IBaseFilter *iface, REFIID riid, void **ppv) SampleGrabber_IBaseFilter_QueryInterface(IBaseFilter *iface, REFIID riid, void **ppv)
{ {
SG_Impl *This = impl_from_IBaseFilter(iface); SG_Impl *This = impl_from_IBaseFilter(iface);
return SampleGrabber_query(This, riid, ppv); return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
} }
/* IUnknown */ /* IUnknown */
...@@ -562,7 +578,7 @@ static ULONG WINAPI ...@@ -562,7 +578,7 @@ static ULONG WINAPI
SampleGrabber_IBaseFilter_AddRef(IBaseFilter *iface) SampleGrabber_IBaseFilter_AddRef(IBaseFilter *iface)
{ {
SG_Impl *This = impl_from_IBaseFilter(iface); SG_Impl *This = impl_from_IBaseFilter(iface);
return SampleGrabber_addref(This); return IUnknown_AddRef(This->outer_unk);
} }
/* IUnknown */ /* IUnknown */
...@@ -570,7 +586,7 @@ static ULONG WINAPI ...@@ -570,7 +586,7 @@ static ULONG WINAPI
SampleGrabber_IBaseFilter_Release(IBaseFilter *iface) SampleGrabber_IBaseFilter_Release(IBaseFilter *iface)
{ {
SG_Impl *This = impl_from_IBaseFilter(iface); SG_Impl *This = impl_from_IBaseFilter(iface);
return SampleGrabber_release(This); return IUnknown_Release(This->outer_unk);
} }
/* IPersist */ /* IPersist */
...@@ -743,7 +759,7 @@ static HRESULT WINAPI ...@@ -743,7 +759,7 @@ static HRESULT WINAPI
SampleGrabber_ISampleGrabber_QueryInterface(ISampleGrabber *iface, REFIID riid, void **ppv) SampleGrabber_ISampleGrabber_QueryInterface(ISampleGrabber *iface, REFIID riid, void **ppv)
{ {
SG_Impl *This = impl_from_ISampleGrabber(iface); SG_Impl *This = impl_from_ISampleGrabber(iface);
return SampleGrabber_query(This, riid, ppv); return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
} }
/* IUnknown */ /* IUnknown */
...@@ -751,7 +767,7 @@ static ULONG WINAPI ...@@ -751,7 +767,7 @@ static ULONG WINAPI
SampleGrabber_ISampleGrabber_AddRef(ISampleGrabber *iface) SampleGrabber_ISampleGrabber_AddRef(ISampleGrabber *iface)
{ {
SG_Impl *This = impl_from_ISampleGrabber(iface); SG_Impl *This = impl_from_ISampleGrabber(iface);
return SampleGrabber_addref(This); return IUnknown_AddRef(This->outer_unk);
} }
/* IUnknown */ /* IUnknown */
...@@ -759,7 +775,7 @@ static ULONG WINAPI ...@@ -759,7 +775,7 @@ static ULONG WINAPI
SampleGrabber_ISampleGrabber_Release(ISampleGrabber *iface) SampleGrabber_ISampleGrabber_Release(ISampleGrabber *iface)
{ {
SG_Impl *This = impl_from_ISampleGrabber(iface); SG_Impl *This = impl_from_ISampleGrabber(iface);
return SampleGrabber_release(This); return IUnknown_Release(This->outer_unk);
} }
/* ISampleGrabber */ /* ISampleGrabber */
...@@ -893,7 +909,7 @@ static HRESULT WINAPI ...@@ -893,7 +909,7 @@ static HRESULT WINAPI
SampleGrabber_IMemInputPin_QueryInterface(IMemInputPin *iface, REFIID riid, void **ppv) SampleGrabber_IMemInputPin_QueryInterface(IMemInputPin *iface, REFIID riid, void **ppv)
{ {
SG_Impl *This = impl_from_IMemInputPin(iface); SG_Impl *This = impl_from_IMemInputPin(iface);
return SampleGrabber_query(This, riid, ppv); return IUnknown_QueryInterface(This->outer_unk, riid, ppv);
} }
/* IUnknown */ /* IUnknown */
...@@ -901,7 +917,7 @@ static ULONG WINAPI ...@@ -901,7 +917,7 @@ static ULONG WINAPI
SampleGrabber_IMemInputPin_AddRef(IMemInputPin *iface) SampleGrabber_IMemInputPin_AddRef(IMemInputPin *iface)
{ {
SG_Impl *This = impl_from_IMemInputPin(iface); SG_Impl *This = impl_from_IMemInputPin(iface);
return SampleGrabber_addref(This); return IUnknown_AddRef(This->outer_unk);
} }
/* IUnknown */ /* IUnknown */
...@@ -909,7 +925,7 @@ static ULONG WINAPI ...@@ -909,7 +925,7 @@ static ULONG WINAPI
SampleGrabber_IMemInputPin_Release(IMemInputPin *iface) SampleGrabber_IMemInputPin_Release(IMemInputPin *iface)
{ {
SG_Impl *This = impl_from_IMemInputPin(iface); SG_Impl *This = impl_from_IMemInputPin(iface);
return SampleGrabber_release(This); return IUnknown_Release(This->outer_unk);
} }
/* IMemInputPin */ /* IMemInputPin */
...@@ -1454,9 +1470,6 @@ HRESULT SampleGrabber_create(IUnknown *pUnkOuter, LPVOID *ppv) ...@@ -1454,9 +1470,6 @@ HRESULT SampleGrabber_create(IUnknown *pUnkOuter, LPVOID *ppv)
TRACE("(%p,%p)\n", ppv, pUnkOuter); TRACE("(%p,%p)\n", ppv, pUnkOuter);
if (pUnkOuter)
return CLASS_E_NOAGGREGATION;
obj = CoTaskMemAlloc(sizeof(SG_Impl)); obj = CoTaskMemAlloc(sizeof(SG_Impl));
if (NULL == obj) { if (NULL == obj) {
*ppv = NULL; *ppv = NULL;
...@@ -1464,7 +1477,8 @@ HRESULT SampleGrabber_create(IUnknown *pUnkOuter, LPVOID *ppv) ...@@ -1464,7 +1477,8 @@ HRESULT SampleGrabber_create(IUnknown *pUnkOuter, LPVOID *ppv)
} }
ZeroMemory(obj, sizeof(SG_Impl)); ZeroMemory(obj, sizeof(SG_Impl));
obj->refCount = 1; obj->ref = 1;
obj->IUnknown_inner.lpVtbl = &samplegrabber_vtbl;
obj->IBaseFilter_iface.lpVtbl = &IBaseFilter_VTable; obj->IBaseFilter_iface.lpVtbl = &IBaseFilter_VTable;
obj->ISampleGrabber_iface.lpVtbl = &ISampleGrabber_VTable; obj->ISampleGrabber_iface.lpVtbl = &ISampleGrabber_VTable;
obj->IMemInputPin_iface.lpVtbl = &IMemInputPin_VTable; obj->IMemInputPin_iface.lpVtbl = &IMemInputPin_VTable;
...@@ -1494,7 +1508,12 @@ HRESULT SampleGrabber_create(IUnknown *pUnkOuter, LPVOID *ppv) ...@@ -1494,7 +1508,12 @@ HRESULT SampleGrabber_create(IUnknown *pUnkOuter, LPVOID *ppv)
obj->oneShot = OneShot_None; obj->oneShot = OneShot_None;
obj->bufferLen = -1; obj->bufferLen = -1;
obj->bufferData = NULL; obj->bufferData = NULL;
*ppv = obj;
if (pUnkOuter)
obj->outer_unk = pUnkOuter;
else
obj->outer_unk = &obj->IUnknown_inner;
*ppv = &obj->IUnknown_inner;
return S_OK; return S_OK;
} }
...@@ -346,8 +346,7 @@ static void test_samplegrabber(void) ...@@ -346,8 +346,7 @@ static void test_samplegrabber(void)
/* COM aggregation */ /* COM aggregation */
hr = CoCreateInstance(&CLSID_SampleGrabber, &unk_obj.IUnknown_iface, CLSCTX_INPROC_SERVER, hr = CoCreateInstance(&CLSID_SampleGrabber, &unk_obj.IUnknown_iface, CLSCTX_INPROC_SERVER,
&IID_IUnknown, (void**)&unk_obj.inner_unk); &IID_IUnknown, (void**)&unk_obj.inner_unk);
todo_wine ok(hr == S_OK, "CoCreateInstance failed: %08x\n", hr); ok(hr == S_OK, "CoCreateInstance failed: %08x\n", hr);
if (hr != S_OK) return;
hr = IUnknown_QueryInterface(unk_obj.inner_unk, &IID_ISampleGrabber, (void**)&sg); hr = IUnknown_QueryInterface(unk_obj.inner_unk, &IID_ISampleGrabber, (void**)&sg);
ok(hr == S_OK, "QueryInterface for IID_ISampleGrabber failed: %08x\n", hr); ok(hr == S_OK, "QueryInterface for IID_ISampleGrabber failed: %08x\n", hr);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment