Improved AVIDec.
Added 2 new callback functions to the transform template and moved all of them into a funcs table.
This commit is contained in:
parent
d5e2b7c843
commit
56c701df3f
|
@ -59,7 +59,7 @@ typedef struct ACMWrapperImpl
|
||||||
BOOL reinit_codec; /* FIXME: Should use sync points instead */
|
BOOL reinit_codec; /* FIXME: Should use sync points instead */
|
||||||
} ACMWrapperImpl;
|
} ACMWrapperImpl;
|
||||||
|
|
||||||
static DWORD ACMWrapper_SendSampleData(TransformFilterImpl* pTransformFilter, LPBYTE data, DWORD size)
|
static HRESULT ACMWrapper_ProcessSampleData(TransformFilterImpl* pTransformFilter, LPBYTE data, DWORD size)
|
||||||
{
|
{
|
||||||
ACMWrapperImpl* This = (ACMWrapperImpl*)pTransformFilter;
|
ACMWrapperImpl* This = (ACMWrapperImpl*)pTransformFilter;
|
||||||
AM_MEDIA_TYPE amt;
|
AM_MEDIA_TYPE amt;
|
||||||
|
@ -230,6 +230,14 @@ static HRESULT ACMWrapper_Cleanup(TransformFilterImpl* pTransformFilter)
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TransformFuncsTable ACMWrapper_FuncsTable = {
|
||||||
|
NULL,
|
||||||
|
ACMWrapper_ProcessSampleData,
|
||||||
|
NULL,
|
||||||
|
ACMWrapper_ConnectInput,
|
||||||
|
ACMWrapper_Cleanup
|
||||||
|
};
|
||||||
|
|
||||||
HRESULT ACMWrapper_create(IUnknown * pUnkOuter, LPVOID * ppv)
|
HRESULT ACMWrapper_create(IUnknown * pUnkOuter, LPVOID * ppv)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -248,7 +256,7 @@ HRESULT ACMWrapper_create(IUnknown * pUnkOuter, LPVOID * ppv)
|
||||||
This->has = 0;
|
This->has = 0;
|
||||||
This->reinit_codec = TRUE;
|
This->reinit_codec = TRUE;
|
||||||
|
|
||||||
hr = TransformFilter_Create(&(This->tf), &CLSID_ACMWrapper, ACMWrapper_SendSampleData, ACMWrapper_ConnectInput, ACMWrapper_Cleanup);
|
hr = TransformFilter_Create(&(This->tf), &CLSID_ACMWrapper, &ACMWrapper_FuncsTable);
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return hr;
|
return hr;
|
||||||
|
|
|
@ -46,6 +46,8 @@
|
||||||
|
|
||||||
WINE_DEFAULT_DEBUG_CHANNEL(quartz);
|
WINE_DEFAULT_DEBUG_CHANNEL(quartz);
|
||||||
|
|
||||||
|
static HRESULT AVIDec_Cleanup(TransformFilterImpl* pTransformFilter);
|
||||||
|
|
||||||
typedef struct AVIDecImpl
|
typedef struct AVIDecImpl
|
||||||
{
|
{
|
||||||
TransformFilterImpl tf;
|
TransformFilterImpl tf;
|
||||||
|
@ -54,7 +56,23 @@ typedef struct AVIDecImpl
|
||||||
BITMAPINFOHEADER* pBihOut;
|
BITMAPINFOHEADER* pBihOut;
|
||||||
} AVIDecImpl;
|
} AVIDecImpl;
|
||||||
|
|
||||||
static DWORD AVIDec_SendSampleData(TransformFilterImpl* pTransformFilter, LPBYTE data, DWORD size)
|
static HRESULT AVIDec_ProcessBegin(TransformFilterImpl* pTransformFilter)
|
||||||
|
{
|
||||||
|
AVIDecImpl* This = (AVIDecImpl*)pTransformFilter;
|
||||||
|
DWORD result;
|
||||||
|
|
||||||
|
TRACE("(%p)->()\n", This);
|
||||||
|
|
||||||
|
result = ICDecompressBegin(This->hvid, This->pBihIn, This->pBihOut);
|
||||||
|
if (result != ICERR_OK)
|
||||||
|
{
|
||||||
|
ERR("Cannot start processing (%ld)\n", result);
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT AVIDec_ProcessSampleData(TransformFilterImpl* pTransformFilter, LPBYTE data, DWORD size)
|
||||||
{
|
{
|
||||||
AVIDecImpl* This = (AVIDecImpl*)pTransformFilter;
|
AVIDecImpl* This = (AVIDecImpl*)pTransformFilter;
|
||||||
VIDEOINFOHEADER* format;
|
VIDEOINFOHEADER* format;
|
||||||
|
@ -115,25 +133,45 @@ error:
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT AVIDec_ProcessEnd(TransformFilterImpl* pTransformFilter)
|
||||||
|
{
|
||||||
|
AVIDecImpl* This = (AVIDecImpl*)pTransformFilter;
|
||||||
|
DWORD result;
|
||||||
|
|
||||||
|
TRACE("(%p)->()\n", This);
|
||||||
|
|
||||||
|
result = ICDecompressEnd(This->hvid);
|
||||||
|
if (result != ICERR_OK)
|
||||||
|
{
|
||||||
|
ERR("Cannot stop processing (%ld)\n", result);
|
||||||
|
return E_FAIL;
|
||||||
|
}
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT AVIDec_ConnectInput(TransformFilterImpl* pTransformFilter, const AM_MEDIA_TYPE * pmt)
|
static HRESULT AVIDec_ConnectInput(TransformFilterImpl* pTransformFilter, const AM_MEDIA_TYPE * pmt)
|
||||||
{
|
{
|
||||||
AVIDecImpl* This = (AVIDecImpl*)pTransformFilter;
|
AVIDecImpl* This = (AVIDecImpl*)pTransformFilter;
|
||||||
|
HRESULT hr = S_FALSE;
|
||||||
|
|
||||||
TRACE("(%p)->(%p)\n", This, pmt);
|
TRACE("(%p)->(%p)\n", This, pmt);
|
||||||
|
|
||||||
|
AVIDec_Cleanup(pTransformFilter);
|
||||||
|
|
||||||
if ((IsEqualIID(&pmt->majortype, &MEDIATYPE_Video)) &&
|
if ((IsEqualIID(&pmt->majortype, &MEDIATYPE_Video)) &&
|
||||||
(!memcmp(((char*)&pmt->subtype)+4, ((char*)&MEDIATYPE_Video)+4, sizeof(GUID)-4)) && /* Check root (GUID w/o FOURCC) */
|
(!memcmp(((char*)&pmt->subtype)+4, ((char*)&MEDIATYPE_Video)+4, sizeof(GUID)-4)) && /* Check root (GUID w/o FOURCC) */
|
||||||
(IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)))
|
(IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo)))
|
||||||
{
|
{
|
||||||
HIC drv;
|
|
||||||
VIDEOINFOHEADER* format = (VIDEOINFOHEADER*)pmt->pbFormat;
|
VIDEOINFOHEADER* format = (VIDEOINFOHEADER*)pmt->pbFormat;
|
||||||
|
|
||||||
drv = ICLocate(pmt->majortype.Data1, pmt->subtype.Data1, &format->bmiHeader, NULL, ICMODE_DECOMPRESS);
|
This->hvid = ICLocate(pmt->majortype.Data1, pmt->subtype.Data1, &format->bmiHeader, NULL, ICMODE_DECOMPRESS);
|
||||||
if (drv)
|
if (This->hvid)
|
||||||
{
|
{
|
||||||
AM_MEDIA_TYPE* outpmt = &((OutputPin*)This->tf.ppPins[1])->pin.mtCurrent;
|
AM_MEDIA_TYPE* outpmt = &((OutputPin*)This->tf.ppPins[1])->pin.mtCurrent;
|
||||||
const CLSID* outsubtype;
|
const CLSID* outsubtype;
|
||||||
DWORD bih_size;
|
DWORD bih_size;
|
||||||
|
DWORD output_depth = format->bmiHeader.biBitCount;
|
||||||
|
DWORD result;
|
||||||
|
|
||||||
switch(format->bmiHeader.biBitCount)
|
switch(format->bmiHeader.biBitCount)
|
||||||
{
|
{
|
||||||
|
@ -142,41 +180,46 @@ static HRESULT AVIDec_ConnectInput(TransformFilterImpl* pTransformFilter, const
|
||||||
case 16: outsubtype = &MEDIASUBTYPE_RGB565; break;
|
case 16: outsubtype = &MEDIASUBTYPE_RGB565; break;
|
||||||
case 8: outsubtype = &MEDIASUBTYPE_RGB8; break;
|
case 8: outsubtype = &MEDIASUBTYPE_RGB8; break;
|
||||||
default:
|
default:
|
||||||
FIXME("Depth %d not supported\n", format->bmiHeader.biBitCount);
|
TRACE("Non standard input depth %d, forced ouptut depth to 32\n", format->bmiHeader.biBitCount);
|
||||||
ICClose(drv);
|
outsubtype = &MEDIASUBTYPE_RGB32;
|
||||||
return S_FALSE;
|
output_depth = 32;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
CopyMediaType(outpmt, pmt);
|
|
||||||
outpmt->subtype = *outsubtype;
|
|
||||||
This->hvid = drv;
|
|
||||||
|
|
||||||
/* Copy bitmap header from media type to 1 for input and 1 for output */
|
/* Copy bitmap header from media type to 1 for input and 1 for output */
|
||||||
if (This->pBihIn) {
|
|
||||||
CoTaskMemFree(This->pBihIn);
|
|
||||||
CoTaskMemFree(This->pBihOut);
|
|
||||||
}
|
|
||||||
bih_size = format->bmiHeader.biSize + format->bmiHeader.biClrUsed * 4;
|
bih_size = format->bmiHeader.biSize + format->bmiHeader.biClrUsed * 4;
|
||||||
This->pBihIn = (BITMAPINFOHEADER*)CoTaskMemAlloc(bih_size);
|
This->pBihIn = (BITMAPINFOHEADER*)CoTaskMemAlloc(bih_size);
|
||||||
if (!This->pBihIn)
|
if (!This->pBihIn)
|
||||||
{
|
{
|
||||||
ICClose(drv);
|
hr = E_OUTOFMEMORY;
|
||||||
return E_OUTOFMEMORY;
|
goto failed;
|
||||||
}
|
}
|
||||||
This->pBihOut = (BITMAPINFOHEADER*)CoTaskMemAlloc(bih_size);
|
This->pBihOut = (BITMAPINFOHEADER*)CoTaskMemAlloc(bih_size);
|
||||||
if (!This->pBihOut)
|
if (!This->pBihOut)
|
||||||
{
|
{
|
||||||
CoTaskMemFree(This->pBihIn);
|
hr = E_OUTOFMEMORY;
|
||||||
This->pBihIn = NULL;
|
goto failed;
|
||||||
ICClose(drv);
|
|
||||||
return E_OUTOFMEMORY;
|
|
||||||
}
|
}
|
||||||
memcpy(This->pBihIn, &format->bmiHeader, bih_size);
|
memcpy(This->pBihIn, &format->bmiHeader, bih_size);
|
||||||
memcpy(This->pBihOut, &format->bmiHeader, bih_size);
|
memcpy(This->pBihOut, &format->bmiHeader, bih_size);
|
||||||
|
|
||||||
/* Update output format as non compressed bitmap */
|
/* Update output format as non compressed bitmap */
|
||||||
This->pBihOut->biCompression = 0;
|
This->pBihOut->biCompression = 0;
|
||||||
|
This->pBihOut->biBitCount = output_depth;
|
||||||
This->pBihOut->biSizeImage = This->pBihOut->biWidth * This->pBihOut->biHeight * This->pBihOut->biBitCount / 8;
|
This->pBihOut->biSizeImage = This->pBihOut->biWidth * This->pBihOut->biHeight * This->pBihOut->biBitCount / 8;
|
||||||
|
|
||||||
|
result = ICDecompressQuery(This->hvid, This->pBihIn, This->pBihOut);
|
||||||
|
if (result != ICERR_OK)
|
||||||
|
{
|
||||||
|
TRACE("Unable to found a suitable output format (%ld)\n", result);
|
||||||
|
goto failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Update output media type */
|
||||||
|
CopyMediaType(outpmt, pmt);
|
||||||
|
outpmt->subtype = *outsubtype;
|
||||||
|
memcpy(&(((VIDEOINFOHEADER*)outpmt->pbFormat)->bmiHeader), This->pBihOut, This->pBihOut->biSize);
|
||||||
|
|
||||||
/* Update buffer size of media samples in output */
|
/* Update buffer size of media samples in output */
|
||||||
((OutputPin*)This->tf.ppPins[1])->allocProps.cbBuffer = This->pBihOut->biSizeImage;
|
((OutputPin*)This->tf.ppPins[1])->allocProps.cbBuffer = This->pBihOut->biSizeImage;
|
||||||
|
|
||||||
|
@ -186,8 +229,11 @@ static HRESULT AVIDec_ConnectInput(TransformFilterImpl* pTransformFilter, const
|
||||||
TRACE("Unable to find a suitable VFW decompressor\n");
|
TRACE("Unable to find a suitable VFW decompressor\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
failed:
|
||||||
|
AVIDec_Cleanup(pTransformFilter);
|
||||||
|
|
||||||
TRACE("Connection refused\n");
|
TRACE("Connection refused\n");
|
||||||
return S_FALSE;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT AVIDec_Cleanup(TransformFilterImpl* pTransformFilter)
|
static HRESULT AVIDec_Cleanup(TransformFilterImpl* pTransformFilter)
|
||||||
|
@ -198,18 +244,26 @@ static HRESULT AVIDec_Cleanup(TransformFilterImpl* pTransformFilter)
|
||||||
|
|
||||||
if (This->hvid)
|
if (This->hvid)
|
||||||
ICClose(This->hvid);
|
ICClose(This->hvid);
|
||||||
|
if (This->pBihIn)
|
||||||
if (This->pBihIn) {
|
|
||||||
CoTaskMemFree(This->pBihIn);
|
CoTaskMemFree(This->pBihIn);
|
||||||
|
if (This->pBihOut)
|
||||||
CoTaskMemFree(This->pBihOut);
|
CoTaskMemFree(This->pBihOut);
|
||||||
}
|
|
||||||
|
|
||||||
This->hvid = NULL;
|
This->hvid = NULL;
|
||||||
This->pBihIn = NULL;
|
This->pBihIn = NULL;
|
||||||
|
This->pBihOut = NULL;
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TransformFuncsTable AVIDec_FuncsTable = {
|
||||||
|
AVIDec_ProcessBegin,
|
||||||
|
AVIDec_ProcessSampleData,
|
||||||
|
AVIDec_ProcessEnd,
|
||||||
|
AVIDec_ConnectInput,
|
||||||
|
AVIDec_Cleanup
|
||||||
|
};
|
||||||
|
|
||||||
HRESULT AVIDec_create(IUnknown * pUnkOuter, LPVOID * ppv)
|
HRESULT AVIDec_create(IUnknown * pUnkOuter, LPVOID * ppv)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -227,8 +281,9 @@ HRESULT AVIDec_create(IUnknown * pUnkOuter, LPVOID * ppv)
|
||||||
|
|
||||||
This->hvid = NULL;
|
This->hvid = NULL;
|
||||||
This->pBihIn = NULL;
|
This->pBihIn = NULL;
|
||||||
|
This->pBihOut = NULL;
|
||||||
|
|
||||||
hr = TransformFilter_Create(&(This->tf), &CLSID_AVIDec, AVIDec_SendSampleData, AVIDec_ConnectInput, AVIDec_Cleanup);
|
hr = TransformFilter_Create(&(This->tf), &CLSID_AVIDec, &AVIDec_FuncsTable);
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
return hr;
|
return hr;
|
||||||
|
|
|
@ -92,7 +92,7 @@ static HRESULT TransformFilter_Sample(LPVOID iface, IMediaSample * pSample)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
This->pfnProcessSample(This, pbSrcStream, cbSrcStream);
|
This->pFuncsTable->pfnProcessSampleData(This, pbSrcStream, cbSrcStream);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,7 @@ static HRESULT TransformFilter_Input_QueryAccept(LPVOID iface, const AM_MEDIA_TY
|
||||||
TRACE("%p\n", iface);
|
TRACE("%p\n", iface);
|
||||||
dump_AM_MEDIA_TYPE(pmt);
|
dump_AM_MEDIA_TYPE(pmt);
|
||||||
|
|
||||||
return This->pfnConnectInput(This, pmt);
|
return This->pFuncsTable->pfnConnectInput(This, pmt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -173,7 +173,7 @@ HRESULT TransformFilter_OutputPin_Construct(const PIN_INFO * pPinInfo, ALLOCATOR
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
HRESULT TransformFilter_Create(TransformFilterImpl* pTransformFilter, const CLSID* pClsid, PFN_PROCESS_SAMPLE pps, PFN_CONNECT_INPUT pci, PFN_CLEANUP pcu)
|
HRESULT TransformFilter_Create(TransformFilterImpl* pTransformFilter, const CLSID* pClsid, TransformFuncsTable* pFuncsTable)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
PIN_INFO piInput;
|
PIN_INFO piInput;
|
||||||
|
@ -181,9 +181,7 @@ HRESULT TransformFilter_Create(TransformFilterImpl* pTransformFilter, const CLSI
|
||||||
|
|
||||||
/* pTransformFilter is already allocated */
|
/* pTransformFilter is already allocated */
|
||||||
pTransformFilter->clsid = *pClsid;
|
pTransformFilter->clsid = *pClsid;
|
||||||
pTransformFilter->pfnProcessSample = pps;
|
pTransformFilter->pFuncsTable = pFuncsTable;
|
||||||
pTransformFilter->pfnConnectInput = pci;
|
|
||||||
pTransformFilter->pfnCleanup = pcu;
|
|
||||||
|
|
||||||
pTransformFilter->lpVtbl = &TransformFilter_Vtbl;
|
pTransformFilter->lpVtbl = &TransformFilter_Vtbl;
|
||||||
|
|
||||||
|
@ -285,7 +283,7 @@ static ULONG WINAPI TransformFilter_Release(IBaseFilter * iface)
|
||||||
HeapFree(GetProcessHeap(), 0, This->ppPins);
|
HeapFree(GetProcessHeap(), 0, This->ppPins);
|
||||||
This->lpVtbl = NULL;
|
This->lpVtbl = NULL;
|
||||||
|
|
||||||
This->pfnCleanup(This);
|
This->pFuncsTable->pfnCleanup(This);
|
||||||
|
|
||||||
TRACE("Destroying transform filter\n");
|
TRACE("Destroying transform filter\n");
|
||||||
CoTaskMemFree(This);
|
CoTaskMemFree(This);
|
||||||
|
@ -320,6 +318,8 @@ static HRESULT WINAPI TransformFilter_Stop(IBaseFilter * iface)
|
||||||
EnterCriticalSection(&This->csFilter);
|
EnterCriticalSection(&This->csFilter);
|
||||||
{
|
{
|
||||||
This->state = State_Stopped;
|
This->state = State_Stopped;
|
||||||
|
if (This->pFuncsTable->pfnProcessEnd)
|
||||||
|
This->pFuncsTable->pfnProcessEnd(This);
|
||||||
}
|
}
|
||||||
LeaveCriticalSection(&This->csFilter);
|
LeaveCriticalSection(&This->csFilter);
|
||||||
|
|
||||||
|
@ -353,6 +353,8 @@ static HRESULT WINAPI TransformFilter_Run(IBaseFilter * iface, REFERENCE_TIME tS
|
||||||
This->rtStreamStart = tStart;
|
This->rtStreamStart = tStart;
|
||||||
This->state = State_Running;
|
This->state = State_Running;
|
||||||
OutputPin_CommitAllocator((OutputPin *)This->ppPins[1]);
|
OutputPin_CommitAllocator((OutputPin *)This->ppPins[1]);
|
||||||
|
if (This->pFuncsTable->pfnProcessBegin)
|
||||||
|
This->pFuncsTable->pfnProcessBegin(This);
|
||||||
}
|
}
|
||||||
LeaveCriticalSection(&This->csFilter);
|
LeaveCriticalSection(&This->csFilter);
|
||||||
|
|
||||||
|
@ -540,7 +542,7 @@ HRESULT WINAPI TransformFilter_Output_Disconnect(IPin * iface)
|
||||||
|
|
||||||
if (hr == S_OK)
|
if (hr == S_OK)
|
||||||
{
|
{
|
||||||
pTransformFilter->pfnCleanup(pTransformFilter);
|
pTransformFilter->pFuncsTable->pfnCleanup(pTransformFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
return hr;
|
return hr;
|
||||||
|
|
|
@ -20,9 +20,13 @@
|
||||||
|
|
||||||
typedef struct TransformFilterImpl TransformFilterImpl;
|
typedef struct TransformFilterImpl TransformFilterImpl;
|
||||||
|
|
||||||
typedef DWORD (*PFN_PROCESS_SAMPLE) (TransformFilterImpl* This, LPBYTE data, DWORD size);
|
typedef struct TransformFuncsTable {
|
||||||
typedef HRESULT (*PFN_CONNECT_INPUT) (TransformFilterImpl* This, const AM_MEDIA_TYPE * pmt);
|
HRESULT (*pfnProcessBegin) (TransformFilterImpl* This);
|
||||||
typedef HRESULT (*PFN_CLEANUP) (TransformFilterImpl* This);
|
HRESULT (*pfnProcessSampleData) (TransformFilterImpl* This, LPBYTE data, DWORD size);
|
||||||
|
HRESULT (*pfnProcessEnd) (TransformFilterImpl* This);
|
||||||
|
HRESULT (*pfnConnectInput) (TransformFilterImpl* This, const AM_MEDIA_TYPE * pmt);
|
||||||
|
HRESULT (*pfnCleanup) (TransformFilterImpl* This);
|
||||||
|
} TransformFuncsTable;
|
||||||
|
|
||||||
struct TransformFilterImpl
|
struct TransformFilterImpl
|
||||||
{
|
{
|
||||||
|
@ -38,9 +42,7 @@ struct TransformFilterImpl
|
||||||
|
|
||||||
IPin ** ppPins;
|
IPin ** ppPins;
|
||||||
|
|
||||||
PFN_PROCESS_SAMPLE pfnProcessSample;
|
TransformFuncsTable * pFuncsTable;
|
||||||
PFN_CONNECT_INPUT pfnConnectInput;
|
|
||||||
PFN_CLEANUP pfnCleanup;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
HRESULT TransformFilter_Create(TransformFilterImpl*, const CLSID*, PFN_PROCESS_SAMPLE, PFN_CONNECT_INPUT, PFN_CLEANUP);
|
HRESULT TransformFilter_Create(TransformFilterImpl*, const CLSID*, TransformFuncsTable* pFuncsTable);
|
||||||
|
|
Loading…
Reference in New Issue