strmbase: Add the EnumMediaTypes base implementation.
This commit is contained in:
parent
ee18ead545
commit
89ea07f7d0
|
@ -32,7 +32,6 @@
|
||||||
#include "qcap_main.h"
|
#include "qcap_main.h"
|
||||||
|
|
||||||
#include "wine/debug.h"
|
#include "wine/debug.h"
|
||||||
#include "wine/strmbase.h"
|
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(qcap);
|
WINE_DEFAULT_DEBUG_CHANNEL(qcap);
|
||||||
|
|
||||||
|
@ -58,183 +57,3 @@ void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE * pmt)
|
||||||
TRACE("\t%s\n\t%s\n\t...\n\t%s\n", debugstr_guid(&pmt->majortype),
|
TRACE("\t%s\n\t%s\n\t...\n\t%s\n", debugstr_guid(&pmt->majortype),
|
||||||
debugstr_guid(&pmt->subtype), debugstr_guid(&pmt->formattype));
|
debugstr_guid(&pmt->subtype), debugstr_guid(&pmt->formattype));
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct IEnumMediaTypesImpl
|
|
||||||
{
|
|
||||||
const IEnumMediaTypesVtbl * lpVtbl;
|
|
||||||
LONG refCount;
|
|
||||||
ENUMMEDIADETAILS enumMediaDetails;
|
|
||||||
ULONG uIndex;
|
|
||||||
} IEnumMediaTypesImpl;
|
|
||||||
|
|
||||||
static const struct IEnumMediaTypesVtbl IEnumMediaTypesImpl_Vtbl;
|
|
||||||
|
|
||||||
HRESULT IEnumMediaTypesImpl_Construct(const ENUMMEDIADETAILS * pDetails,
|
|
||||||
IEnumMediaTypes ** ppEnum)
|
|
||||||
{
|
|
||||||
ULONG i;
|
|
||||||
IEnumMediaTypesImpl * pEnumMediaTypes = CoTaskMemAlloc(sizeof(IEnumMediaTypesImpl));
|
|
||||||
|
|
||||||
if (!pEnumMediaTypes)
|
|
||||||
{
|
|
||||||
*ppEnum = NULL;
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
ObjectRefCount(TRUE);
|
|
||||||
pEnumMediaTypes->lpVtbl = &IEnumMediaTypesImpl_Vtbl;
|
|
||||||
pEnumMediaTypes->refCount = 1;
|
|
||||||
pEnumMediaTypes->uIndex = 0;
|
|
||||||
pEnumMediaTypes->enumMediaDetails.cMediaTypes = pDetails->cMediaTypes;
|
|
||||||
pEnumMediaTypes->enumMediaDetails.pMediaTypes =
|
|
||||||
CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE) * pDetails->cMediaTypes);
|
|
||||||
for (i = 0; i < pDetails->cMediaTypes; i++)
|
|
||||||
if (FAILED(CopyMediaType(&pEnumMediaTypes->enumMediaDetails.pMediaTypes[i], &pDetails->pMediaTypes[i]))) {
|
|
||||||
while (i--) CoTaskMemFree(pEnumMediaTypes->enumMediaDetails.pMediaTypes[i].pbFormat);
|
|
||||||
CoTaskMemFree(pEnumMediaTypes->enumMediaDetails.pMediaTypes);
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
*ppEnum = (IEnumMediaTypes *)(&pEnumMediaTypes->lpVtbl);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI IEnumMediaTypesImpl_QueryInterface(IEnumMediaTypes * iface,
|
|
||||||
REFIID riid,
|
|
||||||
LPVOID * ppv)
|
|
||||||
{
|
|
||||||
TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
|
|
||||||
|
|
||||||
*ppv = NULL;
|
|
||||||
|
|
||||||
if (IsEqualIID(riid, &IID_IUnknown))
|
|
||||||
*ppv = iface;
|
|
||||||
else if (IsEqualIID(riid, &IID_IEnumMediaTypes))
|
|
||||||
*ppv = iface;
|
|
||||||
|
|
||||||
if (*ppv)
|
|
||||||
{
|
|
||||||
IUnknown_AddRef((IUnknown *)(*ppv));
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
FIXME("No interface for %s!\n", debugstr_guid(riid));
|
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ULONG WINAPI IEnumMediaTypesImpl_AddRef(IEnumMediaTypes * iface)
|
|
||||||
{
|
|
||||||
IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
|
|
||||||
ULONG refCount = InterlockedIncrement(&This->refCount);
|
|
||||||
|
|
||||||
TRACE("()\n");
|
|
||||||
|
|
||||||
return refCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ULONG WINAPI IEnumMediaTypesImpl_Release(IEnumMediaTypes * iface)
|
|
||||||
{
|
|
||||||
IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
|
|
||||||
ULONG refCount = InterlockedDecrement(&This->refCount);
|
|
||||||
|
|
||||||
TRACE("()\n");
|
|
||||||
|
|
||||||
if (!refCount)
|
|
||||||
{
|
|
||||||
ULONG i;
|
|
||||||
for (i = 0; i < This->enumMediaDetails.cMediaTypes; i++)
|
|
||||||
if (This->enumMediaDetails.pMediaTypes[i].pbFormat)
|
|
||||||
CoTaskMemFree(This->enumMediaDetails.pMediaTypes[i].pbFormat);
|
|
||||||
CoTaskMemFree(This->enumMediaDetails.pMediaTypes);
|
|
||||||
CoTaskMemFree(This);
|
|
||||||
ObjectRefCount(FALSE);
|
|
||||||
}
|
|
||||||
return refCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI IEnumMediaTypesImpl_Next(IEnumMediaTypes * iface,
|
|
||||||
ULONG cMediaTypes,
|
|
||||||
AM_MEDIA_TYPE ** ppMediaTypes,
|
|
||||||
ULONG * pcFetched)
|
|
||||||
{
|
|
||||||
ULONG cFetched;
|
|
||||||
IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
|
|
||||||
|
|
||||||
cFetched = min(This->enumMediaDetails.cMediaTypes,
|
|
||||||
This->uIndex + cMediaTypes) - This->uIndex;
|
|
||||||
|
|
||||||
TRACE("(%u, %p, %p)\n", cMediaTypes, ppMediaTypes, pcFetched);
|
|
||||||
TRACE("Next uIndex: %u, cFetched: %u\n", This->uIndex, cFetched);
|
|
||||||
|
|
||||||
if (cFetched > 0)
|
|
||||||
{
|
|
||||||
ULONG i;
|
|
||||||
*ppMediaTypes = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE) * cFetched);
|
|
||||||
for (i = 0; i < cFetched; i++)
|
|
||||||
if (FAILED(CopyMediaType(&(*ppMediaTypes)[i], &This->enumMediaDetails.pMediaTypes[This->uIndex + i]))) {
|
|
||||||
while (i--)
|
|
||||||
CoTaskMemFree((*ppMediaTypes)[i].pbFormat);
|
|
||||||
CoTaskMemFree(*ppMediaTypes);
|
|
||||||
*ppMediaTypes = NULL;
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((cMediaTypes != 1) || pcFetched)
|
|
||||||
*pcFetched = cFetched;
|
|
||||||
|
|
||||||
This->uIndex += cFetched;
|
|
||||||
|
|
||||||
if (cFetched != cMediaTypes)
|
|
||||||
return S_FALSE;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI IEnumMediaTypesImpl_Skip(IEnumMediaTypes * iface,
|
|
||||||
ULONG cMediaTypes)
|
|
||||||
{
|
|
||||||
IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
|
|
||||||
|
|
||||||
TRACE("(%u)\n", cMediaTypes);
|
|
||||||
|
|
||||||
if (This->uIndex + cMediaTypes < This->enumMediaDetails.cMediaTypes)
|
|
||||||
{
|
|
||||||
This->uIndex += cMediaTypes;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI IEnumMediaTypesImpl_Reset(IEnumMediaTypes * iface)
|
|
||||||
{
|
|
||||||
IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
|
|
||||||
|
|
||||||
TRACE("()\n");
|
|
||||||
|
|
||||||
This->uIndex = 0;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI IEnumMediaTypesImpl_Clone(IEnumMediaTypes * iface,
|
|
||||||
IEnumMediaTypes ** ppEnum)
|
|
||||||
{
|
|
||||||
HRESULT hr;
|
|
||||||
IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
|
|
||||||
|
|
||||||
TRACE("(%p)\n", ppEnum);
|
|
||||||
|
|
||||||
hr = IEnumMediaTypesImpl_Construct(&This->enumMediaDetails, ppEnum);
|
|
||||||
if (FAILED(hr))
|
|
||||||
return hr;
|
|
||||||
return IEnumMediaTypes_Skip(*ppEnum, This->uIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const IEnumMediaTypesVtbl IEnumMediaTypesImpl_Vtbl =
|
|
||||||
{
|
|
||||||
IEnumMediaTypesImpl_QueryInterface,
|
|
||||||
IEnumMediaTypesImpl_AddRef,
|
|
||||||
IEnumMediaTypesImpl_Release,
|
|
||||||
IEnumMediaTypesImpl_Next,
|
|
||||||
IEnumMediaTypesImpl_Skip,
|
|
||||||
IEnumMediaTypesImpl_Reset,
|
|
||||||
IEnumMediaTypesImpl_Clone
|
|
||||||
};
|
|
||||||
|
|
|
@ -43,7 +43,6 @@ typedef struct IPinImpl
|
||||||
PIN_INFO pinInfo;
|
PIN_INFO pinInfo;
|
||||||
IPin * pConnectedTo;
|
IPin * pConnectedTo;
|
||||||
AM_MEDIA_TYPE mtCurrent;
|
AM_MEDIA_TYPE mtCurrent;
|
||||||
ENUMMEDIADETAILS enumMediaDetails;
|
|
||||||
QUERYACCEPTPROC fnQueryAccept;
|
QUERYACCEPTPROC fnQueryAccept;
|
||||||
LPVOID pUserData;
|
LPVOID pUserData;
|
||||||
} IPinImpl;
|
} IPinImpl;
|
||||||
|
|
|
@ -43,14 +43,7 @@ typedef struct tagENUMPINDETAILS
|
||||||
IPin ** ppPins;
|
IPin ** ppPins;
|
||||||
} ENUMPINDETAILS;
|
} ENUMPINDETAILS;
|
||||||
|
|
||||||
typedef struct tagENUMEDIADETAILS
|
|
||||||
{
|
|
||||||
ULONG cMediaTypes;
|
|
||||||
AM_MEDIA_TYPE * pMediaTypes;
|
|
||||||
} ENUMMEDIADETAILS;
|
|
||||||
|
|
||||||
HRESULT IEnumPinsImpl_Construct(const ENUMPINDETAILS * pDetails, IEnumPins ** ppEnum);
|
HRESULT IEnumPinsImpl_Construct(const ENUMPINDETAILS * pDetails, IEnumPins ** ppEnum);
|
||||||
HRESULT IEnumMediaTypesImpl_Construct(const ENUMMEDIADETAILS * pDetails, IEnumMediaTypes ** ppEnum);
|
|
||||||
|
|
||||||
BOOL CompareMediaTypes(const AM_MEDIA_TYPE * pmt1, const AM_MEDIA_TYPE * pmt2, BOOL bWildcards);
|
BOOL CompareMediaTypes(const AM_MEDIA_TYPE * pmt1, const AM_MEDIA_TYPE * pmt2, BOOL bWildcards);
|
||||||
void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE * pmt);
|
void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE * pmt);
|
||||||
|
|
|
@ -741,6 +741,29 @@ static const IKsPropertySetVtbl KSP_VTable =
|
||||||
KSP_QuerySupported
|
KSP_QuerySupported
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static HRESULT WINAPI VfwPin_GetMediaType(IPin *iface, int iPosition, AM_MEDIA_TYPE *pmt)
|
||||||
|
{
|
||||||
|
VfwPinImpl *This = (VfwPinImpl *)iface;
|
||||||
|
AM_MEDIA_TYPE *vfw_pmt;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (iPosition < 0)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
if (iPosition > 0)
|
||||||
|
return VFW_S_NO_MORE_ITEMS;
|
||||||
|
|
||||||
|
hr = qcap_driver_get_format(This->driver_info, &vfw_pmt);
|
||||||
|
CopyMediaType(pmt, vfw_pmt);
|
||||||
|
DeleteMediaType(vfw_pmt);
|
||||||
|
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
LONG WINAPI VfwPin_GetMediaTypeVersion(IPin *iface)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT
|
static HRESULT
|
||||||
VfwPin_Construct( IBaseFilter * pBaseFilter, LPCRITICAL_SECTION pCritSec,
|
VfwPin_Construct( IBaseFilter * pBaseFilter, LPCRITICAL_SECTION pCritSec,
|
||||||
IPin ** ppPin )
|
IPin ** ppPin )
|
||||||
|
@ -833,18 +856,16 @@ VfwPin_Release(IPin * iface)
|
||||||
static HRESULT WINAPI
|
static HRESULT WINAPI
|
||||||
VfwPin_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum)
|
VfwPin_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum)
|
||||||
{
|
{
|
||||||
ENUMMEDIADETAILS emd;
|
|
||||||
AM_MEDIA_TYPE *pmt;
|
AM_MEDIA_TYPE *pmt;
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
VfwPinImpl *This = (VfwPinImpl *)iface;
|
VfwPinImpl *This = (VfwPinImpl *)iface;
|
||||||
emd.cMediaTypes = 1;
|
|
||||||
hr = qcap_driver_get_format(This->driver_info, &pmt);
|
hr = qcap_driver_get_format(This->driver_info, &pmt);
|
||||||
emd.pMediaTypes = pmt;
|
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
hr = IEnumMediaTypesImpl_Construct(&emd, ppEnum);
|
hr = EnumMediaTypes_Construct(iface, VfwPin_GetMediaType, VfwPin_GetMediaTypeVersion, ppEnum);
|
||||||
TRACE("%p -- %x\n", This, hr);
|
TRACE("%p -- %x\n", This, hr);
|
||||||
DeleteMediaType(pmt);
|
DeleteMediaType(pmt);
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,172 +40,3 @@ void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE * pmt)
|
||||||
return;
|
return;
|
||||||
TRACE("\t%s\n\t%s\n\t...\n\t%s\n", qzdebugstr_guid(&pmt->majortype), qzdebugstr_guid(&pmt->subtype), qzdebugstr_guid(&pmt->formattype));
|
TRACE("\t%s\n\t%s\n\t...\n\t%s\n", qzdebugstr_guid(&pmt->majortype), qzdebugstr_guid(&pmt->subtype), qzdebugstr_guid(&pmt->formattype));
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct IEnumMediaTypesImpl
|
|
||||||
{
|
|
||||||
const IEnumMediaTypesVtbl * lpVtbl;
|
|
||||||
LONG refCount;
|
|
||||||
ENUMMEDIADETAILS enumMediaDetails;
|
|
||||||
ULONG uIndex;
|
|
||||||
} IEnumMediaTypesImpl;
|
|
||||||
|
|
||||||
static const struct IEnumMediaTypesVtbl IEnumMediaTypesImpl_Vtbl;
|
|
||||||
|
|
||||||
HRESULT IEnumMediaTypesImpl_Construct(const ENUMMEDIADETAILS * pDetails, IEnumMediaTypes ** ppEnum)
|
|
||||||
{
|
|
||||||
ULONG i;
|
|
||||||
IEnumMediaTypesImpl * pEnumMediaTypes = CoTaskMemAlloc(sizeof(IEnumMediaTypesImpl));
|
|
||||||
|
|
||||||
if (!pEnumMediaTypes)
|
|
||||||
{
|
|
||||||
*ppEnum = NULL;
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
pEnumMediaTypes->lpVtbl = &IEnumMediaTypesImpl_Vtbl;
|
|
||||||
pEnumMediaTypes->refCount = 1;
|
|
||||||
pEnumMediaTypes->uIndex = 0;
|
|
||||||
pEnumMediaTypes->enumMediaDetails.cMediaTypes = pDetails->cMediaTypes;
|
|
||||||
pEnumMediaTypes->enumMediaDetails.pMediaTypes = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE) * pDetails->cMediaTypes);
|
|
||||||
for (i = 0; i < pDetails->cMediaTypes; i++)
|
|
||||||
if (FAILED(CopyMediaType(&pEnumMediaTypes->enumMediaDetails.pMediaTypes[i], &pDetails->pMediaTypes[i])))
|
|
||||||
{
|
|
||||||
while (i--)
|
|
||||||
CoTaskMemFree(pEnumMediaTypes->enumMediaDetails.pMediaTypes[i].pbFormat);
|
|
||||||
CoTaskMemFree(pEnumMediaTypes->enumMediaDetails.pMediaTypes);
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
*ppEnum = (IEnumMediaTypes *)(&pEnumMediaTypes->lpVtbl);
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI IEnumMediaTypesImpl_QueryInterface(IEnumMediaTypes * iface, REFIID riid, LPVOID * ppv)
|
|
||||||
{
|
|
||||||
TRACE("(%s, %p)\n", qzdebugstr_guid(riid), ppv);
|
|
||||||
|
|
||||||
*ppv = NULL;
|
|
||||||
|
|
||||||
if (IsEqualIID(riid, &IID_IUnknown))
|
|
||||||
*ppv = iface;
|
|
||||||
else if (IsEqualIID(riid, &IID_IEnumMediaTypes))
|
|
||||||
*ppv = iface;
|
|
||||||
|
|
||||||
if (*ppv)
|
|
||||||
{
|
|
||||||
IUnknown_AddRef((IUnknown *)(*ppv));
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
FIXME("No interface for %s!\n", qzdebugstr_guid(riid));
|
|
||||||
|
|
||||||
return E_NOINTERFACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ULONG WINAPI IEnumMediaTypesImpl_AddRef(IEnumMediaTypes * iface)
|
|
||||||
{
|
|
||||||
IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
|
|
||||||
ULONG refCount = InterlockedIncrement(&This->refCount);
|
|
||||||
|
|
||||||
TRACE("(%p)->() AddRef from %d\n", iface, refCount - 1);
|
|
||||||
|
|
||||||
return refCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
static ULONG WINAPI IEnumMediaTypesImpl_Release(IEnumMediaTypes * iface)
|
|
||||||
{
|
|
||||||
IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
|
|
||||||
ULONG refCount = InterlockedDecrement(&This->refCount);
|
|
||||||
|
|
||||||
TRACE("(%p)->() Release from %d\n", iface, refCount + 1);
|
|
||||||
|
|
||||||
if (!refCount)
|
|
||||||
{
|
|
||||||
ULONG i;
|
|
||||||
for (i = 0; i < This->enumMediaDetails.cMediaTypes; i++)
|
|
||||||
if (This->enumMediaDetails.pMediaTypes[i].pbFormat)
|
|
||||||
CoTaskMemFree(This->enumMediaDetails.pMediaTypes[i].pbFormat);
|
|
||||||
CoTaskMemFree(This->enumMediaDetails.pMediaTypes);
|
|
||||||
CoTaskMemFree(This);
|
|
||||||
}
|
|
||||||
return refCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI IEnumMediaTypesImpl_Next(IEnumMediaTypes * iface, ULONG cMediaTypes, AM_MEDIA_TYPE ** ppMediaTypes, ULONG * pcFetched)
|
|
||||||
{
|
|
||||||
ULONG cFetched;
|
|
||||||
IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
|
|
||||||
|
|
||||||
cFetched = min(This->enumMediaDetails.cMediaTypes, This->uIndex + cMediaTypes) - This->uIndex;
|
|
||||||
|
|
||||||
TRACE("(%u, %p, %p)\n", cMediaTypes, ppMediaTypes, pcFetched);
|
|
||||||
TRACE("Next uIndex: %u, cFetched: %u\n", This->uIndex, cFetched);
|
|
||||||
|
|
||||||
if (cFetched > 0)
|
|
||||||
{
|
|
||||||
ULONG i;
|
|
||||||
for (i = 0; i < cFetched; i++)
|
|
||||||
if (!(ppMediaTypes[i] = CreateMediaType(&This->enumMediaDetails.pMediaTypes[This->uIndex + i])))
|
|
||||||
{
|
|
||||||
while (i--)
|
|
||||||
DeleteMediaType(ppMediaTypes[i]);
|
|
||||||
*pcFetched = 0;
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((cMediaTypes != 1) || pcFetched)
|
|
||||||
*pcFetched = cFetched;
|
|
||||||
|
|
||||||
This->uIndex += cFetched;
|
|
||||||
|
|
||||||
if (cFetched != cMediaTypes)
|
|
||||||
return S_FALSE;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI IEnumMediaTypesImpl_Skip(IEnumMediaTypes * iface, ULONG cMediaTypes)
|
|
||||||
{
|
|
||||||
IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
|
|
||||||
|
|
||||||
TRACE("(%u)\n", cMediaTypes);
|
|
||||||
|
|
||||||
if (This->uIndex + cMediaTypes < This->enumMediaDetails.cMediaTypes)
|
|
||||||
{
|
|
||||||
This->uIndex += cMediaTypes;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
return S_FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI IEnumMediaTypesImpl_Reset(IEnumMediaTypes * iface)
|
|
||||||
{
|
|
||||||
IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
|
|
||||||
|
|
||||||
TRACE("()\n");
|
|
||||||
|
|
||||||
This->uIndex = 0;
|
|
||||||
return S_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
static HRESULT WINAPI IEnumMediaTypesImpl_Clone(IEnumMediaTypes * iface, IEnumMediaTypes ** ppEnum)
|
|
||||||
{
|
|
||||||
HRESULT hr;
|
|
||||||
IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
|
|
||||||
|
|
||||||
TRACE("(%p)\n", ppEnum);
|
|
||||||
|
|
||||||
hr = IEnumMediaTypesImpl_Construct(&This->enumMediaDetails, ppEnum);
|
|
||||||
if (FAILED(hr))
|
|
||||||
return hr;
|
|
||||||
return IEnumMediaTypes_Skip(*ppEnum, This->uIndex);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const IEnumMediaTypesVtbl IEnumMediaTypesImpl_Vtbl =
|
|
||||||
{
|
|
||||||
IEnumMediaTypesImpl_QueryInterface,
|
|
||||||
IEnumMediaTypesImpl_AddRef,
|
|
||||||
IEnumMediaTypesImpl_Release,
|
|
||||||
IEnumMediaTypesImpl_Next,
|
|
||||||
IEnumMediaTypesImpl_Skip,
|
|
||||||
IEnumMediaTypesImpl_Reset,
|
|
||||||
IEnumMediaTypesImpl_Clone
|
|
||||||
};
|
|
||||||
|
|
|
@ -794,6 +794,17 @@ static HRESULT AcceptProcAFR(LPVOID iface, const AM_MEDIA_TYPE *pmt)
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI FileAsyncReaderPin_GetMediaType(IPin *iface, int iPosition, AM_MEDIA_TYPE *pmt)
|
||||||
|
{
|
||||||
|
FileAsyncReader *This = (FileAsyncReader *)iface;
|
||||||
|
if (iPosition < 0)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
if (iPosition > 0)
|
||||||
|
return VFW_S_NO_MORE_ITEMS;
|
||||||
|
CopyMediaType(pmt, ((AsyncReader *)This->pin.pin.pinInfo.pFilter)->pmt);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/* overridden pin functions */
|
/* overridden pin functions */
|
||||||
|
|
||||||
static HRESULT WINAPI FileAsyncReaderPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv)
|
static HRESULT WINAPI FileAsyncReaderPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv)
|
||||||
|
@ -850,15 +861,9 @@ static ULONG WINAPI FileAsyncReaderPin_Release(IPin * iface)
|
||||||
|
|
||||||
static HRESULT WINAPI FileAsyncReaderPin_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum)
|
static HRESULT WINAPI FileAsyncReaderPin_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum)
|
||||||
{
|
{
|
||||||
ENUMMEDIADETAILS emd;
|
|
||||||
FileAsyncReader *This = (FileAsyncReader *)iface;
|
|
||||||
|
|
||||||
TRACE("(%p)\n", ppEnum);
|
TRACE("(%p)\n", ppEnum);
|
||||||
|
|
||||||
emd.cMediaTypes = 1;
|
return EnumMediaTypes_Construct(iface, FileAsyncReaderPin_GetMediaType, BasePinImpl_GetMediaTypeVersion, ppEnum);
|
||||||
emd.pMediaTypes = ((AsyncReader *)This->pin.pin.pinInfo.pFilter)->pmt;
|
|
||||||
|
|
||||||
return IEnumMediaTypesImpl_Construct(&emd, ppEnum);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const IPinVtbl FileAsyncReaderPin_Vtbl =
|
static const IPinVtbl FileAsyncReaderPin_Vtbl =
|
||||||
|
|
|
@ -599,6 +599,17 @@ static const IMediaSeekingVtbl Parser_Seeking_Vtbl =
|
||||||
MediaSeekingImpl_GetPreroll
|
MediaSeekingImpl_GetPreroll
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static HRESULT WINAPI Parser_OutputPin_GetMediaType(IPin *iface, int iPosition, AM_MEDIA_TYPE *pmt)
|
||||||
|
{
|
||||||
|
Parser_OutputPin *This = (Parser_OutputPin *)iface;
|
||||||
|
if (iPosition < 0)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
if (iPosition > 0)
|
||||||
|
return VFW_S_NO_MORE_ITEMS;
|
||||||
|
CopyMediaType(pmt, This->pmt);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI Parser_OutputPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv)
|
static HRESULT WINAPI Parser_OutputPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv)
|
||||||
{
|
{
|
||||||
Parser_OutputPin *This = (Parser_OutputPin *)iface;
|
Parser_OutputPin *This = (Parser_OutputPin *)iface;
|
||||||
|
@ -647,16 +658,11 @@ static ULONG WINAPI Parser_OutputPin_Release(IPin * iface)
|
||||||
|
|
||||||
static HRESULT WINAPI Parser_OutputPin_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum)
|
static HRESULT WINAPI Parser_OutputPin_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum)
|
||||||
{
|
{
|
||||||
ENUMMEDIADETAILS emd;
|
|
||||||
Parser_OutputPin *This = (Parser_OutputPin *)iface;
|
|
||||||
|
|
||||||
TRACE("(%p)\n", ppEnum);
|
TRACE("(%p)\n", ppEnum);
|
||||||
|
|
||||||
/* override this method to allow enumeration of your types */
|
/* override this method to allow enumeration of your types */
|
||||||
emd.cMediaTypes = 1;
|
|
||||||
emd.pMediaTypes = This->pmt;
|
|
||||||
|
|
||||||
return IEnumMediaTypesImpl_Construct(&emd, ppEnum);
|
return EnumMediaTypes_Construct(iface, Parser_OutputPin_GetMediaType, BasePinImpl_GetMediaTypeVersion, ppEnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI Parser_OutputPin_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
|
static HRESULT WINAPI Parser_OutputPin_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
|
||||||
|
|
|
@ -154,6 +154,19 @@ static void Copy_PinInfo(PIN_INFO * pDest, const PIN_INFO * pSrc)
|
||||||
pDest->pFilter = pSrc->pFilter;
|
pDest->pFilter = pSrc->pFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*** Common Base Pin function */
|
||||||
|
HRESULT WINAPI BasePinImpl_GetMediaType(IPin *iface, int iPosition, AM_MEDIA_TYPE *pmt)
|
||||||
|
{
|
||||||
|
if (iPosition < 0)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
return VFW_S_NO_MORE_ITEMS;
|
||||||
|
}
|
||||||
|
|
||||||
|
LONG WINAPI BasePinImpl_GetMediaTypeVersion(IPin *iface)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
/*** Common pin functions ***/
|
/*** Common pin functions ***/
|
||||||
|
|
||||||
ULONG WINAPI IPinImpl_AddRef(IPin * iface)
|
ULONG WINAPI IPinImpl_AddRef(IPin * iface)
|
||||||
|
@ -292,15 +305,12 @@ HRESULT WINAPI IPinImpl_QueryAccept(IPin * iface, const AM_MEDIA_TYPE * pmt)
|
||||||
HRESULT WINAPI IPinImpl_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum)
|
HRESULT WINAPI IPinImpl_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum)
|
||||||
{
|
{
|
||||||
IPinImpl *This = (IPinImpl *)iface;
|
IPinImpl *This = (IPinImpl *)iface;
|
||||||
ENUMMEDIADETAILS emd;
|
|
||||||
|
|
||||||
TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
|
TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
|
||||||
|
|
||||||
/* override this method to allow enumeration of your types */
|
/* override this method to allow enumeration of your types */
|
||||||
emd.cMediaTypes = 0;
|
|
||||||
emd.pMediaTypes = NULL;
|
|
||||||
|
|
||||||
return IEnumMediaTypesImpl_Construct(&emd, ppEnum);
|
return EnumMediaTypes_Construct(iface, BasePinImpl_GetMediaType, BasePinImpl_GetMediaTypeVersion , ppEnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT WINAPI IPinImpl_QueryInternalConnections(IPin * iface, IPin ** apPin, ULONG * cPin)
|
HRESULT WINAPI IPinImpl_QueryInternalConnections(IPin * iface, IPin ** apPin, ULONG * cPin)
|
||||||
|
|
|
@ -74,7 +74,6 @@ typedef struct IPinImpl
|
||||||
PIN_INFO pinInfo;
|
PIN_INFO pinInfo;
|
||||||
IPin * pConnectedTo;
|
IPin * pConnectedTo;
|
||||||
AM_MEDIA_TYPE mtCurrent;
|
AM_MEDIA_TYPE mtCurrent;
|
||||||
ENUMMEDIADETAILS enumMediaDetails;
|
|
||||||
QUERYACCEPTPROC fnQueryAccept;
|
QUERYACCEPTPROC fnQueryAccept;
|
||||||
LPVOID pUserData;
|
LPVOID pUserData;
|
||||||
} IPinImpl;
|
} IPinImpl;
|
||||||
|
|
|
@ -63,16 +63,9 @@ HRESULT SeekingPassThru_create(IUnknown *pUnkOuter, LPVOID *ppObj);
|
||||||
|
|
||||||
HRESULT EnumMonikerImpl_Create(IMoniker ** ppMoniker, ULONG nMonikerCount, IEnumMoniker ** ppEnum);
|
HRESULT EnumMonikerImpl_Create(IMoniker ** ppMoniker, ULONG nMonikerCount, IEnumMoniker ** ppEnum);
|
||||||
|
|
||||||
typedef struct tagENUMEDIADETAILS
|
|
||||||
{
|
|
||||||
ULONG cMediaTypes;
|
|
||||||
AM_MEDIA_TYPE * pMediaTypes;
|
|
||||||
} ENUMMEDIADETAILS;
|
|
||||||
|
|
||||||
typedef HRESULT (* FNOBTAINPIN)(IBaseFilter *iface, ULONG pos, IPin **pin, DWORD *lastsynctick);
|
typedef HRESULT (* FNOBTAINPIN)(IBaseFilter *iface, ULONG pos, IPin **pin, DWORD *lastsynctick);
|
||||||
|
|
||||||
HRESULT IEnumPinsImpl_Construct(IEnumPins ** ppEnum, FNOBTAINPIN receive_pin, IBaseFilter *base);
|
HRESULT IEnumPinsImpl_Construct(IEnumPins ** ppEnum, FNOBTAINPIN receive_pin, IBaseFilter *base);
|
||||||
HRESULT IEnumMediaTypesImpl_Construct(const ENUMMEDIADETAILS * pDetails, IEnumMediaTypes ** ppEnum);
|
|
||||||
HRESULT IEnumRegFiltersImpl_Construct(REGFILTER * pInRegFilters, const ULONG size, IEnumRegFilters ** ppEnum);
|
HRESULT IEnumRegFiltersImpl_Construct(REGFILTER * pInRegFilters, const ULONG size, IEnumRegFilters ** ppEnum);
|
||||||
HRESULT IEnumFiltersImpl_Construct(IBaseFilter ** ppFilters, ULONG nFilters, IEnumFilters ** ppEnum);
|
HRESULT IEnumFiltersImpl_Construct(IBaseFilter ** ppFilters, ULONG nFilters, IEnumFilters ** ppEnum);
|
||||||
|
|
||||||
|
@ -94,4 +87,8 @@ typedef struct StdMediaSample2
|
||||||
LONGLONG tMediaEnd;
|
LONGLONG tMediaEnd;
|
||||||
} StdMediaSample2;
|
} StdMediaSample2;
|
||||||
|
|
||||||
|
|
||||||
|
HRESULT WINAPI BasePinImpl_GetMediaType(IPin *iface, int iPosition, AM_MEDIA_TYPE *pmt);
|
||||||
|
LONG WINAPI BasePinImpl_GetMediaTypeVersion(IPin *iface);
|
||||||
|
|
||||||
#endif /* __QUARTZ_PRIVATE_INCLUDED__ */
|
#endif /* __QUARTZ_PRIVATE_INCLUDED__ */
|
||||||
|
|
|
@ -591,18 +591,25 @@ static const IPinVtbl TransformFilter_InputPin_Vtbl =
|
||||||
TransformFilter_InputPin_NewSegment
|
TransformFilter_InputPin_NewSegment
|
||||||
};
|
};
|
||||||
|
|
||||||
static HRESULT WINAPI TransformFilter_Output_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum)
|
static HRESULT WINAPI TransformFilter_Output_GetMediaType(IPin *iface, int iPosition, AM_MEDIA_TYPE *pmt)
|
||||||
{
|
{
|
||||||
IPinImpl *This = (IPinImpl *)iface;
|
IPinImpl *This = (IPinImpl *)iface;
|
||||||
TransformFilterImpl *pTransform = (TransformFilterImpl *)This->pinInfo.pFilter;
|
TransformFilterImpl *pTransform = (TransformFilterImpl *)This->pinInfo.pFilter;
|
||||||
ENUMMEDIADETAILS emd;
|
|
||||||
|
|
||||||
|
if (iPosition < 0)
|
||||||
|
return E_INVALIDARG;
|
||||||
|
if (iPosition > 0)
|
||||||
|
return VFW_S_NO_MORE_ITEMS;
|
||||||
|
CopyMediaType(pmt, &pTransform->pmt);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI TransformFilter_Output_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum)
|
||||||
|
{
|
||||||
|
IPinImpl *This = (IPinImpl *)iface;
|
||||||
TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
|
TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
|
||||||
|
|
||||||
emd.cMediaTypes = 1;
|
return EnumMediaTypes_Construct(iface, TransformFilter_Output_GetMediaType, BasePinImpl_GetMediaTypeVersion, ppEnum);
|
||||||
emd.pMediaTypes = &pTransform->pmt;
|
|
||||||
|
|
||||||
return IEnumMediaTypesImpl_Construct(&emd, ppEnum);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const IPinVtbl TransformFilter_OutputPin_Vtbl =
|
static const IPinVtbl TransformFilter_OutputPin_Vtbl =
|
||||||
|
|
|
@ -76,3 +76,227 @@ void WINAPI DeleteMediaType(AM_MEDIA_TYPE * pMediaType)
|
||||||
FreeMediaType(pMediaType);
|
FreeMediaType(pMediaType);
|
||||||
CoTaskMemFree(pMediaType);
|
CoTaskMemFree(pMediaType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct tagENUMEDIADETAILS
|
||||||
|
{
|
||||||
|
ULONG cMediaTypes;
|
||||||
|
AM_MEDIA_TYPE * pMediaTypes;
|
||||||
|
} ENUMMEDIADETAILS;
|
||||||
|
|
||||||
|
typedef struct IEnumMediaTypesImpl
|
||||||
|
{
|
||||||
|
const IEnumMediaTypesVtbl * lpVtbl;
|
||||||
|
LONG refCount;
|
||||||
|
IPin *basePin;
|
||||||
|
BasePin_GetMediaType enumMediaFunction;
|
||||||
|
BasePin_GetMediaTypeVersion mediaVersionFunction;
|
||||||
|
LONG currentVersion;
|
||||||
|
ENUMMEDIADETAILS enumMediaDetails;
|
||||||
|
ULONG uIndex;
|
||||||
|
} IEnumMediaTypesImpl;
|
||||||
|
|
||||||
|
static const struct IEnumMediaTypesVtbl IEnumMediaTypesImpl_Vtbl;
|
||||||
|
|
||||||
|
HRESULT WINAPI EnumMediaTypes_Construct(IPin *basePin, BasePin_GetMediaType enumFunc, BasePin_GetMediaTypeVersion versionFunc, IEnumMediaTypes ** ppEnum)
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
IEnumMediaTypesImpl * pEnumMediaTypes = CoTaskMemAlloc(sizeof(IEnumMediaTypesImpl));
|
||||||
|
AM_MEDIA_TYPE amt;
|
||||||
|
|
||||||
|
if (!pEnumMediaTypes)
|
||||||
|
{
|
||||||
|
*ppEnum = NULL;
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
pEnumMediaTypes->lpVtbl = &IEnumMediaTypesImpl_Vtbl;
|
||||||
|
pEnumMediaTypes->refCount = 1;
|
||||||
|
pEnumMediaTypes->uIndex = 0;
|
||||||
|
pEnumMediaTypes->enumMediaFunction = enumFunc;
|
||||||
|
pEnumMediaTypes->mediaVersionFunction = versionFunc;
|
||||||
|
IPin_AddRef(basePin);
|
||||||
|
pEnumMediaTypes->basePin = basePin;
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (enumFunc(basePin,i,&amt) == S_OK) i++;
|
||||||
|
|
||||||
|
pEnumMediaTypes->enumMediaDetails.cMediaTypes = i;
|
||||||
|
pEnumMediaTypes->enumMediaDetails.pMediaTypes = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE) * i);
|
||||||
|
for (i = 0; i < pEnumMediaTypes->enumMediaDetails.cMediaTypes; i++)
|
||||||
|
{
|
||||||
|
enumFunc(basePin,i,&amt);
|
||||||
|
if (FAILED(CopyMediaType(&pEnumMediaTypes->enumMediaDetails.pMediaTypes[i], &amt)))
|
||||||
|
{
|
||||||
|
while (i--)
|
||||||
|
CoTaskMemFree(pEnumMediaTypes->enumMediaDetails.pMediaTypes[i].pbFormat);
|
||||||
|
CoTaskMemFree(pEnumMediaTypes->enumMediaDetails.pMediaTypes);
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*ppEnum = (IEnumMediaTypes *)(&pEnumMediaTypes->lpVtbl);
|
||||||
|
pEnumMediaTypes->currentVersion = versionFunc(basePin);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI IEnumMediaTypesImpl_QueryInterface(IEnumMediaTypes * iface, REFIID riid, LPVOID * ppv)
|
||||||
|
{
|
||||||
|
TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
|
||||||
|
|
||||||
|
*ppv = NULL;
|
||||||
|
|
||||||
|
if (IsEqualIID(riid, &IID_IUnknown))
|
||||||
|
*ppv = iface;
|
||||||
|
else if (IsEqualIID(riid, &IID_IEnumMediaTypes))
|
||||||
|
*ppv = iface;
|
||||||
|
|
||||||
|
if (*ppv)
|
||||||
|
{
|
||||||
|
IUnknown_AddRef((IUnknown *)(*ppv));
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
FIXME("No interface for %s!\n", debugstr_guid(riid));
|
||||||
|
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI IEnumMediaTypesImpl_AddRef(IEnumMediaTypes * iface)
|
||||||
|
{
|
||||||
|
IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
|
||||||
|
ULONG refCount = InterlockedIncrement(&This->refCount);
|
||||||
|
|
||||||
|
TRACE("(%p)->() AddRef from %d\n", iface, refCount - 1);
|
||||||
|
|
||||||
|
return refCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI IEnumMediaTypesImpl_Release(IEnumMediaTypes * iface)
|
||||||
|
{
|
||||||
|
IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
|
||||||
|
ULONG refCount = InterlockedDecrement(&This->refCount);
|
||||||
|
|
||||||
|
TRACE("(%p)->() Release from %d\n", iface, refCount + 1);
|
||||||
|
|
||||||
|
if (!refCount)
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
for (i = 0; i < This->enumMediaDetails.cMediaTypes; i++)
|
||||||
|
if (This->enumMediaDetails.pMediaTypes[i].pbFormat)
|
||||||
|
CoTaskMemFree(This->enumMediaDetails.pMediaTypes[i].pbFormat);
|
||||||
|
CoTaskMemFree(This->enumMediaDetails.pMediaTypes);
|
||||||
|
IPin_Release(This->basePin);
|
||||||
|
CoTaskMemFree(This);
|
||||||
|
}
|
||||||
|
return refCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI IEnumMediaTypesImpl_Next(IEnumMediaTypes * iface, ULONG cMediaTypes, AM_MEDIA_TYPE ** ppMediaTypes, ULONG * pcFetched)
|
||||||
|
{
|
||||||
|
ULONG cFetched;
|
||||||
|
IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
|
||||||
|
|
||||||
|
cFetched = min(This->enumMediaDetails.cMediaTypes, This->uIndex + cMediaTypes) - This->uIndex;
|
||||||
|
|
||||||
|
if (This->currentVersion != This->mediaVersionFunction(This->basePin))
|
||||||
|
return VFW_E_ENUM_OUT_OF_SYNC;
|
||||||
|
|
||||||
|
TRACE("(%u, %p, %p)\n", cMediaTypes, ppMediaTypes, pcFetched);
|
||||||
|
TRACE("Next uIndex: %u, cFetched: %u\n", This->uIndex, cFetched);
|
||||||
|
|
||||||
|
if (cFetched > 0)
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
for (i = 0; i < cFetched; i++)
|
||||||
|
if (!(ppMediaTypes[i] = CreateMediaType(&This->enumMediaDetails.pMediaTypes[This->uIndex + i])))
|
||||||
|
{
|
||||||
|
while (i--)
|
||||||
|
DeleteMediaType(ppMediaTypes[i]);
|
||||||
|
*pcFetched = 0;
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((cMediaTypes != 1) || pcFetched)
|
||||||
|
*pcFetched = cFetched;
|
||||||
|
|
||||||
|
This->uIndex += cFetched;
|
||||||
|
|
||||||
|
if (cFetched != cMediaTypes)
|
||||||
|
return S_FALSE;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI IEnumMediaTypesImpl_Skip(IEnumMediaTypes * iface, ULONG cMediaTypes)
|
||||||
|
{
|
||||||
|
IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
|
||||||
|
|
||||||
|
TRACE("(%u)\n", cMediaTypes);
|
||||||
|
if (This->currentVersion != This->mediaVersionFunction(This->basePin))
|
||||||
|
return VFW_E_ENUM_OUT_OF_SYNC;
|
||||||
|
|
||||||
|
if (This->uIndex + cMediaTypes < This->enumMediaDetails.cMediaTypes)
|
||||||
|
{
|
||||||
|
This->uIndex += cMediaTypes;
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
return S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI IEnumMediaTypesImpl_Reset(IEnumMediaTypes * iface)
|
||||||
|
{
|
||||||
|
ULONG i;
|
||||||
|
AM_MEDIA_TYPE amt;
|
||||||
|
IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
|
||||||
|
|
||||||
|
TRACE("()\n");
|
||||||
|
|
||||||
|
for (i = 0; i < This->enumMediaDetails.cMediaTypes; i++)
|
||||||
|
if (This->enumMediaDetails.pMediaTypes[i].pbFormat)
|
||||||
|
CoTaskMemFree(This->enumMediaDetails.pMediaTypes[i].pbFormat);
|
||||||
|
CoTaskMemFree(This->enumMediaDetails.pMediaTypes);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
while (This->enumMediaFunction(This->basePin, i,&amt) == S_OK) i++;
|
||||||
|
|
||||||
|
This->enumMediaDetails.cMediaTypes = i;
|
||||||
|
This->enumMediaDetails.pMediaTypes = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE) * i);
|
||||||
|
for (i = 0; i < This->enumMediaDetails.cMediaTypes; i++)
|
||||||
|
{
|
||||||
|
This->enumMediaFunction(This->basePin, i,&amt);
|
||||||
|
if (FAILED(CopyMediaType(&This->enumMediaDetails.pMediaTypes[i], &amt)))
|
||||||
|
{
|
||||||
|
while (i--)
|
||||||
|
CoTaskMemFree(This->enumMediaDetails.pMediaTypes[i].pbFormat);
|
||||||
|
CoTaskMemFree(This->enumMediaDetails.pMediaTypes);
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
This->currentVersion = This->mediaVersionFunction(This->basePin);
|
||||||
|
This->uIndex = 0;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI IEnumMediaTypesImpl_Clone(IEnumMediaTypes * iface, IEnumMediaTypes ** ppEnum)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
IEnumMediaTypesImpl *This = (IEnumMediaTypesImpl *)iface;
|
||||||
|
|
||||||
|
TRACE("(%p)\n", ppEnum);
|
||||||
|
|
||||||
|
hr = EnumMediaTypes_Construct(This->basePin, This->enumMediaFunction, This->mediaVersionFunction, ppEnum);
|
||||||
|
if (FAILED(hr))
|
||||||
|
return hr;
|
||||||
|
return IEnumMediaTypes_Skip(*ppEnum, This->uIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IEnumMediaTypesVtbl IEnumMediaTypesImpl_Vtbl =
|
||||||
|
{
|
||||||
|
IEnumMediaTypesImpl_QueryInterface,
|
||||||
|
IEnumMediaTypesImpl_AddRef,
|
||||||
|
IEnumMediaTypesImpl_Release,
|
||||||
|
IEnumMediaTypesImpl_Next,
|
||||||
|
IEnumMediaTypesImpl_Skip,
|
||||||
|
IEnumMediaTypesImpl_Reset,
|
||||||
|
IEnumMediaTypesImpl_Clone
|
||||||
|
};
|
||||||
|
|
|
@ -23,3 +23,8 @@ HRESULT WINAPI CopyMediaType(AM_MEDIA_TYPE * pDest, const AM_MEDIA_TYPE *pSrc);
|
||||||
void WINAPI FreeMediaType(AM_MEDIA_TYPE * pMediaType);
|
void WINAPI FreeMediaType(AM_MEDIA_TYPE * pMediaType);
|
||||||
AM_MEDIA_TYPE * WINAPI CreateMediaType(AM_MEDIA_TYPE const * pSrc);
|
AM_MEDIA_TYPE * WINAPI CreateMediaType(AM_MEDIA_TYPE const * pSrc);
|
||||||
void WINAPI DeleteMediaType(AM_MEDIA_TYPE * pMediaType);
|
void WINAPI DeleteMediaType(AM_MEDIA_TYPE * pMediaType);
|
||||||
|
|
||||||
|
typedef HRESULT (WINAPI *BasePin_GetMediaType)(IPin* iface, int iPosition, AM_MEDIA_TYPE *amt);
|
||||||
|
typedef LONG (WINAPI *BasePin_GetMediaTypeVersion)(IPin* iface);
|
||||||
|
|
||||||
|
HRESULT WINAPI EnumMediaTypes_Construct(IPin *iface, BasePin_GetMediaType enumFunc, BasePin_GetMediaTypeVersion versionFunc, IEnumMediaTypes ** ppEnum);
|
||||||
|
|
Loading…
Reference in New Issue