strmbase: Clean up the allocator negotiating for BaseOutputPin.

This commit is contained in:
Aric Stewart 2010-10-13 10:46:27 -05:00 committed by Alexandre Julliard
parent 1826530974
commit 8f3c3723bb
9 changed files with 160 additions and 64 deletions

View file

@ -669,30 +669,38 @@ LONG WINAPI VfwPin_GetMediaTypeVersion(IPin *iface)
return 1;
}
static HRESULT WINAPI VfwPin_DecideBufferSize(IPin *iface, IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest)
{
ALLOCATOR_PROPERTIES actual;
/* What we put here doesn't matter, the
driver function should override it then commit */
if (!ppropInputRequest->cBuffers)
ppropInputRequest->cBuffers = 3;
if (!ppropInputRequest->cbBuffer)
ppropInputRequest->cbBuffer = 230400;
if (!ppropInputRequest->cbAlign)
ppropInputRequest->cbAlign = 1;
return IMemAllocator_SetProperties(pAlloc, ppropInputRequest, &actual);
}
static HRESULT
VfwPin_Construct( IBaseFilter * pBaseFilter, LPCRITICAL_SECTION pCritSec,
IPin ** ppPin )
{
static const WCHAR wszOutputPinName[] = { 'O','u','t','p','u','t',0 };
ALLOCATOR_PROPERTIES ap;
PIN_INFO piOutput;
HRESULT hr;
ppPin = NULL;
/* What we put here doesn't matter, the
driver function should override it then commit */
ap.cBuffers = 3;
ap.cbBuffer = 230400;
ap.cbAlign = 1;
ap.cbPrefix = 0;
piOutput.dir = PINDIR_OUTPUT;
piOutput.pFilter = pBaseFilter;
lstrcpyW(piOutput.achName, wszOutputPinName);
ObjectRefCount(TRUE);
hr = BaseOutputPin_Construct(&VfwPin_Vtbl, sizeof(VfwPinImpl), &piOutput, &ap, NULL, pCritSec, ppPin);
hr = BaseOutputPin_Construct(&VfwPin_Vtbl, sizeof(VfwPinImpl), &piOutput, VfwPin_DecideBufferSize, NULL, pCritSec, ppPin);
if (SUCCEEDED(hr))
{

View file

@ -264,8 +264,6 @@ static HRESULT WINAPI ACMWrapper_SetMediaType(TransformFilter *tf, PIN_DIRECTION
{
This->has = drv;
/* Update buffer size of media samples in output */
((BaseOutputPin*)This->tf.ppPins[1])->allocProps.cbBuffer = This->pWfOut->nAvgBytesPerSec / 2;
TRACE("Connection accepted\n");
return S_OK;
}
@ -294,8 +292,6 @@ static HRESULT WINAPI ACMWrapper_CompleteConnect(TransformFilter *tf, PIN_DIRECT
{
This->has = drv;
/* Update buffer size of media samples in output */
((BaseOutputPin*)This->tf.ppPins[1])->allocProps.cbBuffer = This->pWfOut->nAvgBytesPerSec / 2;
TRACE("Connection accepted\n");
return S_OK;
}
@ -323,7 +319,25 @@ static HRESULT WINAPI ACMWrapper_BreakConnect(TransformFilter *tf, PIN_DIRECTION
return S_OK;
}
static HRESULT WINAPI ACMWrapper_DecideBufferSize(TransformFilter *tf, IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest)
{
ACMWrapperImpl *pACM = (ACMWrapperImpl*)tf;
ALLOCATOR_PROPERTIES actual;
if (!ppropInputRequest->cbAlign)
ppropInputRequest->cbAlign = 1;
if (ppropInputRequest->cbBuffer < pACM->pWfOut->nAvgBytesPerSec / 2)
ppropInputRequest->cbBuffer = pACM->pWfOut->nAvgBytesPerSec / 2;
if (!ppropInputRequest->cBuffers)
ppropInputRequest->cBuffers = 1;
return IMemAllocator_SetProperties(pAlloc, ppropInputRequest, &actual);
}
static const TransformFilterFuncTable ACMWrapper_FuncsTable = {
ACMWrapper_DecideBufferSize,
NULL,
ACMWrapper_Receive,
NULL,

View file

@ -279,11 +279,6 @@ static HRESULT WINAPI AVIDec_CompleteConnect(TransformFilter *tf, PIN_DIRECTION
TRACE("(%p)\n", This);
if (dir == PINDIR_INPUT)
{
/* Update buffer size of media samples in output */
((BaseOutputPin*)This->tf.ppPins[1])->allocProps.cbBuffer = This->pBihOut->biSizeImage;
}
return S_OK;
}
@ -310,7 +305,25 @@ static HRESULT WINAPI AVIDec_BreakConnect(TransformFilter *tf, PIN_DIRECTION dir
return S_OK;
}
static HRESULT WINAPI AVIDec_DecideBufferSize(TransformFilter *tf, IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest)
{
AVIDecImpl *pAVI = (AVIDecImpl*)tf;
ALLOCATOR_PROPERTIES actual;
if (!ppropInputRequest->cbAlign)
ppropInputRequest->cbAlign = 1;
if (ppropInputRequest->cbBuffer < pAVI->pBihOut->biSizeImage)
ppropInputRequest->cbBuffer = pAVI->pBihOut->biSizeImage;
if (!ppropInputRequest->cBuffers)
ppropInputRequest->cBuffers = 1;
return IMemAllocator_SetProperties(pAlloc, ppropInputRequest, &actual);
}
static const TransformFilterFuncTable AVIDec_FuncsTable = {
AVIDec_DecideBufferSize,
AVIDec_StartStreaming,
AVIDec_Receive,
AVIDec_StopStreaming,

View file

@ -656,6 +656,7 @@ typedef struct FileAsyncReader
BaseOutputPin pin;
const struct IAsyncReaderVtbl * lpVtblAR;
ALLOCATOR_PROPERTIES allocProps;
HANDLE hFile;
BOOL bFlushing;
/* Why would you need more? Every sample has its own handle */
@ -814,6 +815,24 @@ static HRESULT WINAPI FileAsyncReaderPin_AttemptConnection(IPin * iface, IPin *
return hr;
}
static HRESULT WINAPI FileAsyncReaderPin_DecideBufferSize(IPin *iface, IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest)
{
FileAsyncReader *This = (FileAsyncReader *)iface;
ALLOCATOR_PROPERTIES actual;
if (ppropInputRequest->cbAlign && ppropInputRequest->cbAlign != This->allocProps.cbAlign)
FIXME("Requested Buffer cbAlign mismatch %i,%i\n",This->allocProps.cbAlign, ppropInputRequest->cbAlign);
if (ppropInputRequest->cbPrefix)
FIXME("Requested Buffer cbPrefix mismatch %i,%i\n",This->allocProps.cbPrefix, ppropInputRequest->cbPrefix);
if (ppropInputRequest->cbBuffer)
FIXME("Requested Buffer cbBuffer mismatch %i,%i\n",This->allocProps.cbBuffer, ppropInputRequest->cbBuffer);
if (ppropInputRequest->cBuffers)
FIXME("Requested Buffer cBuffers mismatch %i,%i\n",This->allocProps.cBuffers, ppropInputRequest->cBuffers);
return IMemAllocator_SetProperties(pAlloc, &This->allocProps, &actual);
}
static HRESULT FileAsyncReader_Construct(HANDLE hFile, IBaseFilter * pBaseFilter, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
{
PIN_INFO piOutput;
@ -823,7 +842,7 @@ static HRESULT FileAsyncReader_Construct(HANDLE hFile, IBaseFilter * pBaseFilter
piOutput.dir = PINDIR_OUTPUT;
piOutput.pFilter = pBaseFilter;
strcpyW(piOutput.achName, wszOutputPinName);
hr = BaseOutputPin_Construct(&FileAsyncReaderPin_Vtbl, sizeof(FileAsyncReader), &piOutput, NULL, FileAsyncReaderPin_AttemptConnection, pCritSec, ppPin);
hr = BaseOutputPin_Construct(&FileAsyncReaderPin_Vtbl, sizeof(FileAsyncReader), &piOutput, FileAsyncReaderPin_DecideBufferSize, FileAsyncReaderPin_AttemptConnection, pCritSec, ppPin);
if (SUCCEEDED(hr))
{
@ -933,7 +952,7 @@ done:
This->handle_list[This->samples + 1 + x] = This->handle_list[x];
}
This->handle_list[This->samples] = CreateEventW(NULL, 1, 0, NULL);
This->pin.allocProps = *pProps;
This->allocProps = *pProps;
}
else
{

View file

@ -43,6 +43,7 @@ static const IPinVtbl Parser_InputPin_Vtbl;
static HRESULT WINAPI Parser_ChangeStart(IMediaSeeking *iface);
static HRESULT WINAPI Parser_ChangeStop(IMediaSeeking *iface);
static HRESULT WINAPI Parser_ChangeRate(IMediaSeeking *iface);
static HRESULT WINAPI Parser_OutputPin_DecideBufferSize(IPin *iface, IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest);
static inline ParserImpl *impl_from_IMediaSeeking( IMediaSeeking *iface )
{
@ -411,7 +412,7 @@ HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PR
This->ppPins = CoTaskMemAlloc((This->cStreams + 2) * sizeof(IPin *));
memcpy(This->ppPins, ppOldPins, (This->cStreams + 1) * sizeof(IPin *));
hr = BaseOutputPin_Construct(&Parser_OutputPin_Vtbl, sizeof(Parser_OutputPin), piOutput, props, NULL, &This->filter.csFilter, This->ppPins + (This->cStreams + 1));
hr = BaseOutputPin_Construct(&Parser_OutputPin_Vtbl, sizeof(Parser_OutputPin), piOutput, Parser_OutputPin_DecideBufferSize, NULL, &This->filter.csFilter, This->ppPins + (This->cStreams + 1));
if (SUCCEEDED(hr))
{
@ -423,6 +424,7 @@ HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PR
pin->pin.pin.pinInfo.pFilter = (LPVOID)This;
pin->pin.custom_allocator = 1;
pin->allocProps = *props;
This->cStreams++;
BaseFilterImpl_IncrementPinVersion((IBaseFilter*)This);
CoTaskMemFree(ppOldPins);
@ -528,6 +530,23 @@ static const IMediaSeekingVtbl Parser_Seeking_Vtbl =
SourceSeekingImpl_GetPreroll
};
static HRESULT WINAPI Parser_OutputPin_DecideBufferSize(IPin *iface, IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest)
{
Parser_OutputPin *This = (Parser_OutputPin *)iface;
ALLOCATOR_PROPERTIES actual;
if (ppropInputRequest->cbAlign && ppropInputRequest->cbAlign != This->allocProps.cbAlign)
FIXME("Requested Buffer cbAlign mismatch %i,%i\n",This->allocProps.cbAlign, ppropInputRequest->cbAlign);
if (ppropInputRequest->cbPrefix)
FIXME("Requested Buffer cbPrefix mismatch %i,%i\n",This->allocProps.cbPrefix, ppropInputRequest->cbPrefix);
if (ppropInputRequest->cbBuffer)
FIXME("Requested Buffer cbBuffer mismatch %i,%i\n",This->allocProps.cbBuffer, ppropInputRequest->cbBuffer);
if (ppropInputRequest->cBuffers)
FIXME("Requested Buffer cBuffers mismatch %i,%i\n",This->allocProps.cBuffers, ppropInputRequest->cBuffers);
return IMemAllocator_SetProperties(pAlloc, &This->allocProps, &actual);
}
static HRESULT WINAPI Parser_OutputPin_GetMediaType(IPin *iface, int iPosition, AM_MEDIA_TYPE *pmt)
{
Parser_OutputPin *This = (Parser_OutputPin *)iface;

View file

@ -45,6 +45,7 @@ typedef struct Parser_OutputPin
AM_MEDIA_TYPE * pmt;
LONGLONG dwSamplesProcessed;
ALLOCATOR_PROPERTIES allocProps;
} Parser_OutputPin;
extern HRESULT Parser_AddPin(ParserImpl * This, const PIN_INFO * piOutput, ALLOCATOR_PROPERTIES * props, const AM_MEDIA_TYPE * amt);

View file

@ -721,6 +721,48 @@ HRESULT WINAPI BaseOutputPinImpl_BreakConnect(BaseOutputPin *This)
return hr;
}
HRESULT WINAPI BaseOutputPinImpl_InitAllocator(BaseOutputPin *This, IMemAllocator **pMemAlloc)
{
return CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER, &IID_IMemAllocator, (LPVOID*)pMemAlloc);
}
HRESULT WINAPI BaseOutputPinImpl_DecideAllocator(BaseOutputPin *This, IMemInputPin *pPin, IMemAllocator **pAlloc)
{
HRESULT hr;
if (!This->custom_allocator)
{
hr = IMemInputPin_GetAllocator(pPin, pAlloc);
if (hr == VFW_E_NO_ALLOCATOR)
/* Input pin provides no allocator, use standard memory allocator */
hr = BaseOutputPinImpl_InitAllocator(This, pAlloc);
if (SUCCEEDED(hr))
{
ALLOCATOR_PROPERTIES rProps;
ZeroMemory(&rProps, sizeof(ALLOCATOR_PROPERTIES));
IMemInputPin_GetAllocatorRequirements(pPin, &rProps);
hr = This->pDecideBufferSize((IPin*)This, *pAlloc, &rProps);
}
if (SUCCEEDED(hr))
hr = IMemInputPin_NotifyAllocator(pPin, *pAlloc, This->readonly);
}
else
{
pAlloc = NULL;
if (This->alloc)
hr = IMemInputPin_NotifyAllocator(pPin, This->alloc, This->readonly);
else
hr = VFW_E_NO_ALLOCATOR;
}
return hr;
}
/*** The Construct functions ***/
/* Function called as a helper to IPin_Connect */
@ -730,7 +772,6 @@ static HRESULT WINAPI OutputPin_AttemptConnection(IPin * iface, IPin * pReceiveP
BaseOutputPin *This = (BaseOutputPin *)iface;
HRESULT hr;
IMemAllocator * pMemAlloc = NULL;
ALLOCATOR_PROPERTIES actual; /* FIXME: should we put the actual props back in to This? */
TRACE("(%p, %p)\n", pReceivePin, pmt);
dump_AM_MEDIA_TYPE(pmt);
@ -750,32 +791,12 @@ static HRESULT WINAPI OutputPin_AttemptConnection(IPin * iface, IPin * pReceiveP
This->pMemInputPin = NULL;
hr = IPin_QueryInterface(pReceivePin, &IID_IMemInputPin, (LPVOID)&This->pMemInputPin);
if (SUCCEEDED(hr) && !This->custom_allocator)
if (SUCCEEDED(hr))
{
hr = IMemInputPin_GetAllocator(This->pMemInputPin, &pMemAlloc);
if (hr == VFW_E_NO_ALLOCATOR)
/* Input pin provides no allocator, use standard memory allocator */
hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER, &IID_IMemAllocator, (LPVOID*)&pMemAlloc);
if (SUCCEEDED(hr))
hr = IMemAllocator_SetProperties(pMemAlloc, &This->allocProps, &actual);
if (SUCCEEDED(hr))
hr = IMemInputPin_NotifyAllocator(This->pMemInputPin, pMemAlloc, This->readonly);
hr = BaseOutputPinImpl_DecideAllocator(This, This->pMemInputPin, &pMemAlloc);
if (pMemAlloc)
IMemAllocator_Release(pMemAlloc);
}
else if (SUCCEEDED(hr))
{
if (This->alloc)
{
hr = IMemInputPin_NotifyAllocator(This->pMemInputPin, This->alloc, This->readonly);
}
else
hr = VFW_E_NO_ALLOCATOR;
}
/* break connection if we couldn't get the allocator */
if (FAILED(hr))
@ -800,7 +821,7 @@ static HRESULT WINAPI OutputPin_AttemptConnection(IPin * iface, IPin * pReceiveP
}
static HRESULT OutputPin_Init(const IPinVtbl *OutputPin_Vtbl, const PIN_INFO *
pPinInfo, const ALLOCATOR_PROPERTIES * props, BasePin_AttemptConnection pConnectProc, LPCRITICAL_SECTION pCritSec,
pPinInfo, BaseOutputPin_DecideBufferSize pBufferProc, BasePin_AttemptConnection pConnectProc, LPCRITICAL_SECTION pCritSec,
BaseOutputPin * pPinImpl)
{
TRACE("\n");
@ -819,25 +840,19 @@ BaseOutputPin * pPinImpl)
pPinImpl->pAttemptConnection = pConnectProc;
else
pPinImpl->pAttemptConnection = OutputPin_AttemptConnection;
pPinImpl->pDecideBufferSize = pBufferProc;
/* If custom_allocator is set, you will need to specify an allocator
* in the alloc member of the struct before an output pin can connect
*/
pPinImpl->custom_allocator = 0;
pPinImpl->alloc = NULL;
pPinImpl->readonly = FALSE;
if (props)
{
pPinImpl->allocProps = *props;
if (pPinImpl->allocProps.cbAlign == 0)
pPinImpl->allocProps.cbAlign = 1;
}
else
ZeroMemory(&pPinImpl->allocProps, sizeof(pPinImpl->allocProps));
return S_OK;
}
HRESULT WINAPI BaseOutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, LONG outputpin_size, const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *props, BasePin_AttemptConnection pConnectProc, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
HRESULT WINAPI BaseOutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, LONG outputpin_size, const PIN_INFO * pPinInfo, BaseOutputPin_DecideBufferSize pBufferProc, BasePin_AttemptConnection pConnectProc, LPCRITICAL_SECTION pCritSec, IPin ** ppPin)
{
BaseOutputPin * pPinImpl;
@ -856,7 +871,7 @@ HRESULT WINAPI BaseOutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, LONG outp
if (!pPinImpl)
return E_OUTOFMEMORY;
if (SUCCEEDED(OutputPin_Init(OutputPin_Vtbl, pPinInfo, props, pConnectProc, pCritSec, pPinImpl)))
if (SUCCEEDED(OutputPin_Init(OutputPin_Vtbl, pPinInfo, pBufferProc, pConnectProc, pCritSec, pPinImpl)))
{
*ppPin = (IPin *)(&pPinImpl->pin.lpVtbl);
return S_OK;

View file

@ -103,6 +103,13 @@ static HRESULT WINAPI TransformFilter_Output_QueryAccept(IPin *iface, const AM_M
return S_FALSE;
}
static HRESULT WINAPI TransformFilter_Output_DecideBufferSize(IPin *iface, IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest)
{
BasePin *This = (BasePin *)iface;
TransformFilter *pTransformFilter = (TransformFilter *)This->pinInfo.pFilter;
return pTransformFilter->pFuncsTable->pfnDecideBufferSize(pTransformFilter, pAlloc, ppropInputRequest);
}
static IPin* WINAPI TransformFilter_GetPin(IBaseFilter *iface, int pos)
{
TransformFilter *This = (TransformFilter *)iface;
@ -148,13 +155,7 @@ static HRESULT TransformFilter_Init(const IBaseFilterVtbl *pVtbl, const CLSID* p
if (SUCCEEDED(hr))
{
ALLOCATOR_PROPERTIES props;
props.cbAlign = 1;
props.cbPrefix = 0;
props.cbBuffer = 0; /* Will be updated at connection time */
props.cBuffers = 1;
hr = BaseOutputPin_Construct(&TransformFilter_OutputPin_Vtbl, sizeof(BaseOutputPin), &piOutput, &props, NULL, &pTransformFilter->filter.csFilter, &pTransformFilter->ppPins[1]);
hr = BaseOutputPin_Construct(&TransformFilter_OutputPin_Vtbl, sizeof(BaseOutputPin), &piOutput, TransformFilter_Output_DecideBufferSize, NULL, &pTransformFilter->filter.csFilter, &pTransformFilter->ppPins[1]);
if (FAILED(hr))
ERR("Cannot create output pin (%x)\n", hr);

View file

@ -28,6 +28,7 @@ typedef HRESULT (WINAPI *BasePin_GetMediaType)(IPin* iface, int iPosition, AM_ME
typedef LONG (WINAPI *BasePin_GetMediaTypeVersion)(IPin* iface);
typedef HRESULT (WINAPI *BasePin_AttemptConnection)(IPin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt);
typedef HRESULT (WINAPI *BasePin_CheckMediaType)(IPin *iface, const AM_MEDIA_TYPE *pmt);
typedef HRESULT (WINAPI *BaseOutputPin_DecideBufferSize)(IPin *iface, IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest);
typedef IPin* (WINAPI *BaseFilter_GetPin)(IBaseFilter* iface, int iPosition);
typedef LONG (WINAPI *BaseFilter_GetPinCount)(IBaseFilter* iface);
@ -58,10 +59,10 @@ typedef struct BaseOutputPin
IMemInputPin * pMemInputPin;
BasePin_AttemptConnection pAttemptConnection;
BaseOutputPin_DecideBufferSize pDecideBufferSize;
BOOL custom_allocator;
IMemAllocator *alloc;
BOOL readonly;
ALLOCATOR_PROPERTIES allocProps;
} BaseOutputPin;
typedef struct BaseInputPin
@ -110,7 +111,10 @@ HRESULT WINAPI BaseOutputPinImpl_Deliver(BaseOutputPin * This, IMediaSample * pS
HRESULT WINAPI BaseOutputPinImpl_BreakConnect(BaseOutputPin * This);
HRESULT WINAPI BaseOutputPinImpl_Active(BaseOutputPin * This);
HRESULT WINAPI BaseOutputPinImpl_Inactive(BaseOutputPin * This);
HRESULT WINAPI BaseOutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, LONG outputpin_size, const PIN_INFO * pPinInfo, ALLOCATOR_PROPERTIES *props, BasePin_AttemptConnection pConnectProc, LPCRITICAL_SECTION pCritSec, IPin ** ppPin);
HRESULT WINAPI BaseOutputPinImpl_InitAllocator(BaseOutputPin *This, IMemAllocator **pMemAlloc);
HRESULT WINAPI BaseOutputPinImpl_DecideAllocator(BaseOutputPin *This, IMemInputPin *pPin, IMemAllocator **pAlloc);
HRESULT WINAPI BaseOutputPin_Construct(const IPinVtbl *OutputPin_Vtbl, LONG outputpin_size, const PIN_INFO * pPinInfo, BaseOutputPin_DecideBufferSize pBufferProc, BasePin_AttemptConnection pConnectProc, LPCRITICAL_SECTION pCritSec, IPin ** ppPin);
/* Base Input Pin */
HRESULT WINAPI BaseInputPinImpl_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv);
@ -171,6 +175,7 @@ typedef struct TransformFilter
const struct TransformFilterFuncTable * pFuncsTable;
} TransformFilter;
typedef HRESULT (WINAPI *TransformFilter_DecideBufferSize) (TransformFilter *iface, IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest);
typedef HRESULT (WINAPI *TransformFilter_StartStreaming) (TransformFilter *iface);
typedef HRESULT (WINAPI *TransformFilter_StopStreaming) (TransformFilter *iface);
typedef HRESULT (WINAPI *TransformFilter_Receive) (TransformFilter* iface, IMediaSample* pIn);
@ -185,6 +190,7 @@ typedef HRESULT (WINAPI *TransformFilter_NewSegment) (TransformFilter *iface,
REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
typedef struct TransformFilterFuncTable {
TransformFilter_DecideBufferSize pfnDecideBufferSize;
TransformFilter_StartStreaming pfnStartStreaming;
TransformFilter_Receive pfnReceive;
TransformFilter_StopStreaming pfnStopStreaming;