strmbase: Add the EnumMediaTypes base implementation.
This commit is contained in:
parent
ee18ead545
commit
89ea07f7d0
|
@ -32,7 +32,6 @@
|
|||
#include "qcap_main.h"
|
||||
|
||||
#include "wine/debug.h"
|
||||
#include "wine/strmbase.h"
|
||||
|
||||
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),
|
||||
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;
|
||||
IPin * pConnectedTo;
|
||||
AM_MEDIA_TYPE mtCurrent;
|
||||
ENUMMEDIADETAILS enumMediaDetails;
|
||||
QUERYACCEPTPROC fnQueryAccept;
|
||||
LPVOID pUserData;
|
||||
} IPinImpl;
|
||||
|
|
|
@ -43,14 +43,7 @@ typedef struct tagENUMPINDETAILS
|
|||
IPin ** ppPins;
|
||||
} ENUMPINDETAILS;
|
||||
|
||||
typedef struct tagENUMEDIADETAILS
|
||||
{
|
||||
ULONG cMediaTypes;
|
||||
AM_MEDIA_TYPE * pMediaTypes;
|
||||
} ENUMMEDIADETAILS;
|
||||
|
||||
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);
|
||||
void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE * pmt);
|
||||
|
|
|
@ -741,6 +741,29 @@ static const IKsPropertySetVtbl KSP_VTable =
|
|||
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
|
||||
VfwPin_Construct( IBaseFilter * pBaseFilter, LPCRITICAL_SECTION pCritSec,
|
||||
IPin ** ppPin )
|
||||
|
@ -833,18 +856,16 @@ VfwPin_Release(IPin * iface)
|
|||
static HRESULT WINAPI
|
||||
VfwPin_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnum)
|
||||
{
|
||||
ENUMMEDIADETAILS emd;
|
||||
AM_MEDIA_TYPE *pmt;
|
||||
HRESULT hr;
|
||||
|
||||
VfwPinImpl *This = (VfwPinImpl *)iface;
|
||||
emd.cMediaTypes = 1;
|
||||
hr = qcap_driver_get_format(This->driver_info, &pmt);
|
||||
emd.pMediaTypes = pmt;
|
||||
if (SUCCEEDED(hr))
|
||||
hr = IEnumMediaTypesImpl_Construct(&emd, ppEnum);
|
||||
hr = EnumMediaTypes_Construct(iface, VfwPin_GetMediaType, VfwPin_GetMediaTypeVersion, ppEnum);
|
||||
TRACE("%p -- %x\n", This, hr);
|
||||
DeleteMediaType(pmt);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
|
|
|
@ -40,172 +40,3 @@ void dump_AM_MEDIA_TYPE(const AM_MEDIA_TYPE * pmt)
|
|||
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));
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 */
|
||||
|
||||
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)
|
||||
{
|
||||
ENUMMEDIADETAILS emd;
|
||||
FileAsyncReader *This = (FileAsyncReader *)iface;
|
||||
|
||||
TRACE("(%p)\n", ppEnum);
|
||||
|
||||
emd.cMediaTypes = 1;
|
||||
emd.pMediaTypes = ((AsyncReader *)This->pin.pin.pinInfo.pFilter)->pmt;
|
||||
|
||||
return IEnumMediaTypesImpl_Construct(&emd, ppEnum);
|
||||
return EnumMediaTypes_Construct(iface, FileAsyncReaderPin_GetMediaType, BasePinImpl_GetMediaTypeVersion, ppEnum);
|
||||
}
|
||||
|
||||
static const IPinVtbl FileAsyncReaderPin_Vtbl =
|
||||
|
|
|
@ -599,6 +599,17 @@ static const IMediaSeekingVtbl Parser_Seeking_Vtbl =
|
|||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
ENUMMEDIADETAILS emd;
|
||||
Parser_OutputPin *This = (Parser_OutputPin *)iface;
|
||||
|
||||
TRACE("(%p)\n", ppEnum);
|
||||
|
||||
/* 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)
|
||||
|
|
|
@ -154,6 +154,19 @@ static void Copy_PinInfo(PIN_INFO * pDest, const PIN_INFO * pSrc)
|
|||
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 ***/
|
||||
|
||||
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)
|
||||
{
|
||||
IPinImpl *This = (IPinImpl *)iface;
|
||||
ENUMMEDIADETAILS emd;
|
||||
|
||||
TRACE("(%p/%p)->(%p)\n", This, iface, ppEnum);
|
||||
|
||||
/* 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)
|
||||
|
|
|
@ -74,7 +74,6 @@ typedef struct IPinImpl
|
|||
PIN_INFO pinInfo;
|
||||
IPin * pConnectedTo;
|
||||
AM_MEDIA_TYPE mtCurrent;
|
||||
ENUMMEDIADETAILS enumMediaDetails;
|
||||
QUERYACCEPTPROC fnQueryAccept;
|
||||
LPVOID pUserData;
|
||||
} IPinImpl;
|
||||
|
|
|
@ -63,16 +63,9 @@ HRESULT SeekingPassThru_create(IUnknown *pUnkOuter, LPVOID *ppObj);
|
|||
|
||||
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);
|
||||
|
||||
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 IEnumFiltersImpl_Construct(IBaseFilter ** ppFilters, ULONG nFilters, IEnumFilters ** ppEnum);
|
||||
|
||||
|
@ -94,4 +87,8 @@ typedef struct StdMediaSample2
|
|||
LONGLONG tMediaEnd;
|
||||
} StdMediaSample2;
|
||||
|
||||
|
||||
HRESULT WINAPI BasePinImpl_GetMediaType(IPin *iface, int iPosition, AM_MEDIA_TYPE *pmt);
|
||||
LONG WINAPI BasePinImpl_GetMediaTypeVersion(IPin *iface);
|
||||
|
||||
#endif /* __QUARTZ_PRIVATE_INCLUDED__ */
|
||||
|
|
|
@ -591,18 +591,25 @@ static const IPinVtbl TransformFilter_InputPin_Vtbl =
|
|||
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;
|
||||
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);
|
||||
|
||||
emd.cMediaTypes = 1;
|
||||
emd.pMediaTypes = &pTransform->pmt;
|
||||
|
||||
return IEnumMediaTypesImpl_Construct(&emd, ppEnum);
|
||||
return EnumMediaTypes_Construct(iface, TransformFilter_Output_GetMediaType, BasePinImpl_GetMediaTypeVersion, ppEnum);
|
||||
}
|
||||
|
||||
static const IPinVtbl TransformFilter_OutputPin_Vtbl =
|
||||
|
|
|
@ -76,3 +76,227 @@ void WINAPI DeleteMediaType(AM_MEDIA_TYPE * pMediaType)
|
|||
FreeMediaType(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);
|
||||
AM_MEDIA_TYPE * WINAPI CreateMediaType(AM_MEDIA_TYPE const * pSrc);
|
||||
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