qedit: Add pins enumerator implementation to SampleGrabber.
This commit is contained in:
parent
076fdb35ba
commit
43fe5e35b8
|
@ -36,6 +36,160 @@ static WCHAR const vendor_name[] = { 'W', 'i', 'n', 'e', 0 };
|
|||
static WCHAR const pin_in_name[] = { 'I', 'n', 0 };
|
||||
static WCHAR const pin_out_name[] = { 'O', 'u', 't', 0 };
|
||||
|
||||
IEnumPins *pinsenum_create(IBaseFilter *filter, IPin **pins, ULONG pinCount);
|
||||
|
||||
/* Fixed pins enumerator, holds filter referenced */
|
||||
typedef struct _PE_Impl {
|
||||
IEnumPins pe;
|
||||
IBaseFilter *filter;
|
||||
LONG refCount;
|
||||
ULONG numPins;
|
||||
ULONG index;
|
||||
IPin *pins[0];
|
||||
} PE_Impl;
|
||||
|
||||
|
||||
/* IEnumPins interface implementation */
|
||||
|
||||
/* IUnknown */
|
||||
static ULONG WINAPI
|
||||
Fixed_IEnumPins_AddRef(IEnumPins *iface)
|
||||
{
|
||||
PE_Impl *This = (PE_Impl *)iface;
|
||||
ULONG refCount = InterlockedIncrement(&This->refCount);
|
||||
TRACE("(%p) new ref = %u\n", This, refCount);
|
||||
return refCount;
|
||||
}
|
||||
|
||||
/* IUnknown */
|
||||
static ULONG WINAPI
|
||||
Fixed_IEnumPins_Release(IEnumPins *iface)
|
||||
{
|
||||
PE_Impl *This = (PE_Impl *)iface;
|
||||
ULONG refCount = InterlockedDecrement(&This->refCount);
|
||||
TRACE("(%p) new ref = %u\n", This, refCount);
|
||||
if (refCount == 0)
|
||||
{
|
||||
IBaseFilter_Release(This->filter);
|
||||
CoTaskMemFree(This);
|
||||
return 0;
|
||||
}
|
||||
return refCount;
|
||||
}
|
||||
|
||||
/* IUnknown */
|
||||
static HRESULT WINAPI
|
||||
Fixed_IEnumPins_QueryInterface(IEnumPins *iface, REFIID riid, void **ppvObject)
|
||||
{
|
||||
PE_Impl *This = (PE_Impl *)iface;
|
||||
TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject);
|
||||
|
||||
if (IsEqualIID(riid, &IID_IUnknown) ||
|
||||
IsEqualIID(riid, &IID_IEnumPins)) {
|
||||
Fixed_IEnumPins_AddRef(iface);
|
||||
*ppvObject = &(This->pins);
|
||||
return S_OK;
|
||||
}
|
||||
*ppvObject = NULL;
|
||||
WARN("(%p, %s,%p): not found\n", This, debugstr_guid(riid), ppvObject);
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
/* IEnumPins */
|
||||
static HRESULT WINAPI
|
||||
Fixed_IEnumPins_Next(IEnumPins *iface, ULONG nPins, IPin **pins, ULONG *fetched)
|
||||
{
|
||||
PE_Impl *This = (PE_Impl *)iface;
|
||||
ULONG count = 0;
|
||||
TRACE("(%p)->(%u, %p, %p) index = %u\n", This, nPins, pins, fetched, This->index);
|
||||
if (!nPins)
|
||||
return E_INVALIDARG;
|
||||
if (!pins || ((nPins != 1) && !fetched))
|
||||
return E_POINTER;
|
||||
while ((count < nPins) && (This->index < This->numPins)) {
|
||||
IPin *pin = This->pins[This->index++];
|
||||
IPin_AddRef(pin);
|
||||
pins[count++] = pin;
|
||||
}
|
||||
if (fetched)
|
||||
*fetched = count;
|
||||
return (count == nPins) ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
/* IEnumPins */
|
||||
static HRESULT WINAPI
|
||||
Fixed_IEnumPins_Skip(IEnumPins *iface, ULONG nPins)
|
||||
{
|
||||
PE_Impl *This = (PE_Impl *)iface;
|
||||
TRACE("(%p)->(%u) index = %u\n", This, nPins, This->index);
|
||||
nPins += This->index;
|
||||
if (nPins >= This->numPins) {
|
||||
This->index = This->numPins;
|
||||
return S_FALSE;
|
||||
}
|
||||
This->index = nPins;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* IEnumPins */
|
||||
static HRESULT WINAPI
|
||||
Fixed_IEnumPins_Reset(IEnumPins *iface)
|
||||
{
|
||||
PE_Impl *This = (PE_Impl *)iface;
|
||||
TRACE("(%p)->() index = %u\n", This, This->index);
|
||||
This->index = 0;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* IEnumPins */
|
||||
static HRESULT WINAPI
|
||||
Fixed_IEnumPins_Clone(IEnumPins *iface, IEnumPins **pins)
|
||||
{
|
||||
PE_Impl *This = (PE_Impl *)iface;
|
||||
TRACE("(%p)->(%p) index = %u\n", This, pins, This->index);
|
||||
if (!pins)
|
||||
return E_POINTER;
|
||||
*pins = pinsenum_create(This->filter, This->pins, This->numPins);
|
||||
if (!*pins)
|
||||
return E_OUTOFMEMORY;
|
||||
((PE_Impl *)*pins)->index = This->index;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
/* Virtual tables and constructor */
|
||||
|
||||
static const IEnumPinsVtbl IEnumPins_VTable =
|
||||
{
|
||||
Fixed_IEnumPins_QueryInterface,
|
||||
Fixed_IEnumPins_AddRef,
|
||||
Fixed_IEnumPins_Release,
|
||||
Fixed_IEnumPins_Next,
|
||||
Fixed_IEnumPins_Skip,
|
||||
Fixed_IEnumPins_Reset,
|
||||
Fixed_IEnumPins_Clone,
|
||||
};
|
||||
|
||||
IEnumPins *pinsenum_create(IBaseFilter *filter, IPin **pins, ULONG pinCount)
|
||||
{
|
||||
ULONG len = sizeof(PE_Impl) + (pinCount * sizeof(IPin *));
|
||||
PE_Impl *obj = CoTaskMemAlloc(len);
|
||||
if (obj) {
|
||||
ULONG i;
|
||||
ZeroMemory(obj, len);
|
||||
obj->pe.lpVtbl = &IEnumPins_VTable;
|
||||
obj->refCount = 1;
|
||||
obj->filter = filter;
|
||||
obj->numPins = pinCount;
|
||||
obj->index = 0;
|
||||
for (i=0; i<pinCount; i++)
|
||||
obj->pins[i] = pins[i];
|
||||
IBaseFilter_AddRef(filter);
|
||||
}
|
||||
return &obj->pe;
|
||||
}
|
||||
|
||||
|
||||
/* Sample Grabber pin implementation */
|
||||
typedef struct _SG_Pin {
|
||||
const IPinVtbl* lpVtbl;
|
||||
|
@ -314,10 +468,14 @@ static HRESULT WINAPI
|
|||
SampleGrabber_IBaseFilter_EnumPins(IBaseFilter *iface, IEnumPins **pins)
|
||||
{
|
||||
SG_Impl *This = impl_from_IBaseFilter(iface);
|
||||
FIXME("(%p)->(%p): stub\n", This, pins);
|
||||
IPin *pin[2];
|
||||
TRACE("(%p)->(%p)\n", This, pins);
|
||||
if (!pins)
|
||||
return E_POINTER;
|
||||
return E_OUTOFMEMORY;
|
||||
pin[0] = (IPin*)&This->pin_in.lpVtbl;
|
||||
pin[1] = (IPin*)&This->pin_out.lpVtbl;
|
||||
*pins = pinsenum_create(iface, pin, 2);
|
||||
return *pins ? S_OK : E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
/* IBaseFilter */
|
||||
|
|
Loading…
Reference in New Issue