mirror of
https://github.com/reactos/wine.git
synced 2024-11-28 14:10:32 +00:00
qedit: Support COM aggregation for SampleGrabber.
This commit is contained in:
parent
703d0a33ce
commit
7367685021
@ -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)
|
|||||||
|
|
||||||
/* 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 {
|
|||||||
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,62 +437,72 @@ 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Common helper Release called from all interfaces */
|
TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
|
||||||
static ULONG SampleGrabber_release(SG_Impl *This)
|
|
||||||
{
|
|
||||||
ULONG refCount = InterlockedDecrement(&This->refCount);
|
|
||||||
TRACE("(%p) new ref = %u\n", This, refCount);
|
|
||||||
if (refCount == 0)
|
|
||||||
{
|
|
||||||
SampleGrabber_cleanup(This);
|
|
||||||
CoTaskMemFree(This);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return refCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Common helper QueryInterface called from all interfaces */
|
*ppv = NULL;
|
||||||
static HRESULT SampleGrabber_query(SG_Impl *This, REFIID riid, void **ppvObject)
|
if (IsEqualIID(riid, &IID_IUnknown))
|
||||||
{
|
*ppv = &This->IUnknown_inner;
|
||||||
TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
|
else if (IsEqualIID(riid, &IID_IPersist) || IsEqualIID(riid, &IID_IMediaFilter) ||
|
||||||
|
IsEqualIID(riid, &IID_IBaseFilter))
|
||||||
if (IsEqualIID(riid, &IID_IUnknown) ||
|
*ppv = &This->IBaseFilter_iface;
|
||||||
IsEqualIID(riid, &IID_IPersist) ||
|
else if (IsEqualIID(riid, &IID_ISampleGrabber))
|
||||||
IsEqualIID(riid, &IID_IMediaFilter) ||
|
*ppv = &This->ISampleGrabber_iface;
|
||||||
IsEqualIID(riid, &IID_IBaseFilter)) {
|
else if (IsEqualIID(riid, &IID_IMemInputPin))
|
||||||
SampleGrabber_addref(This);
|
*ppv = &This->IMemInputPin_iface;
|
||||||
*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))
|
else if (IsEqualIID(riid, &IID_IMediaPosition))
|
||||||
FIXME("IMediaPosition not implemented\n");
|
FIXME("IMediaPosition not implemented\n");
|
||||||
else if (IsEqualIID(riid, &IID_IMediaSeeking))
|
else if (IsEqualIID(riid, &IID_IMediaSeeking))
|
||||||
FIXME("IMediaSeeking not implemented\n");
|
FIXME("IMediaSeeking not implemented\n");
|
||||||
else if (IsEqualIID(riid, &IID_IQualityControl))
|
else if (IsEqualIID(riid, &IID_IQualityControl))
|
||||||
FIXME("IQualityControl not implemented\n");
|
FIXME("IQualityControl not implemented\n");
|
||||||
*ppvObject = NULL;
|
else
|
||||||
WARN("(%p, %s,%p): not found\n", This, debugstr_guid(riid), ppvObject);
|
WARN("(%p, %s,%p): not found\n", This, debugstr_guid(riid), ppv);
|
||||||
return E_NOINTERFACE;
|
|
||||||
|
if (!*ppv)
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
|
||||||
|
IUnknown_AddRef((IUnknown*)*ppv);
|
||||||
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI SampleGrabber_AddRef(IUnknown *iface)
|
||||||
|
{
|
||||||
|
SG_Impl *This = impl_from_IUnknown(iface);
|
||||||
|
ULONG ref = InterlockedIncrement(&This->ref);
|
||||||
|
|
||||||
|
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);
|
||||||
|
CoTaskMemFree(This);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return ref;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IUnknownVtbl samplegrabber_vtbl =
|
||||||
|
{
|
||||||
|
SampleGrabber_QueryInterface,
|
||||||
|
SampleGrabber_AddRef,
|
||||||
|
SampleGrabber_Release,
|
||||||
|
};
|
||||||
|
|
||||||
/* 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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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
|
|||||||
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)
|
|||||||
|
|
||||||
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)
|
|||||||
}
|
}
|
||||||
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)
|
|||||||
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)
|
|||||||
/* 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);
|
||||||
|
Loading…
Reference in New Issue
Block a user