strmbase: Combine the SetMediaType() and CompleteConnect() callbacks.

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2019-12-10 10:35:11 -06:00 committed by Alexandre Julliard
parent 4b49875ec1
commit 264c539ed6
6 changed files with 101 additions and 230 deletions

View File

@ -40,7 +40,6 @@ typedef struct ACMWrapperImpl
TransformFilter tf;
HACMSTREAM has;
LPWAVEFORMATEX pWfIn;
LPWAVEFORMATEX pWfOut;
LONGLONG lasttime_real;
@ -224,85 +223,43 @@ error:
return hr;
}
static HRESULT WINAPI ACMWrapper_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE * pmt)
static BOOL is_audio_subtype(const GUID *guid)
{
ACMWrapperImpl* This = impl_from_TransformFilter(tf);
MMRESULT res;
TRACE("(%p)->(%i %p)\n", This, dir, pmt);
if (dir != PINDIR_INPUT)
return S_OK;
/* Check root (GUID w/o FOURCC) */
if ((IsEqualIID(&pmt->majortype, &MEDIATYPE_Audio)) &&
(!memcmp(((const char *)&pmt->subtype)+4, ((const char *)&MEDIATYPE_Audio)+4, sizeof(GUID)-4)) &&
(IsEqualIID(&pmt->formattype, &FORMAT_WaveFormatEx)))
{
HACMSTREAM drv;
WAVEFORMATEX *wfx = (WAVEFORMATEX*)pmt->pbFormat;
AM_MEDIA_TYPE* outpmt = &This->tf.pmt;
if (!wfx || wfx->wFormatTag == WAVE_FORMAT_PCM || wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
return VFW_E_TYPE_NOT_ACCEPTED;
FreeMediaType(outpmt);
This->pWfIn = (LPWAVEFORMATEX)pmt->pbFormat;
/* HACK */
/* TRACE("ALIGN = %d\n", pACMWrapper->pWfIn->nBlockAlign); */
/* pACMWrapper->pWfIn->nBlockAlign = 1; */
/* Set output audio data to PCM */
CopyMediaType(outpmt, pmt);
outpmt->subtype.Data1 = WAVE_FORMAT_PCM;
This->pWfOut = (WAVEFORMATEX*)outpmt->pbFormat;
This->pWfOut->wFormatTag = WAVE_FORMAT_PCM;
This->pWfOut->wBitsPerSample = 16;
This->pWfOut->nBlockAlign = This->pWfOut->wBitsPerSample * This->pWfOut->nChannels / 8;
This->pWfOut->cbSize = 0;
This->pWfOut->nAvgBytesPerSec = This->pWfOut->nChannels * This->pWfOut->nSamplesPerSec
* (This->pWfOut->wBitsPerSample/8);
if (!(res = acmStreamOpen(&drv, NULL, This->pWfIn, This->pWfOut, NULL, 0, 0, 0)))
{
This->has = drv;
TRACE("Connection accepted\n");
return S_OK;
}
else
FIXME("acmStreamOpen returned %d\n", res);
FreeMediaType(outpmt);
TRACE("Unable to find a suitable ACM decompressor\n");
}
TRACE("Connection refused\n");
return VFW_E_TYPE_NOT_ACCEPTED;
return !memcmp(&guid->Data2, &MEDIATYPE_Audio.Data2, sizeof(GUID) - sizeof(int));
}
static HRESULT WINAPI ACMWrapper_CompleteConnect(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin)
static HRESULT acm_wrapper_connect_sink(TransformFilter *iface, const AM_MEDIA_TYPE *mt)
{
ACMWrapperImpl* This = impl_from_TransformFilter(tf);
MMRESULT res;
ACMWrapperImpl *filter = impl_from_TransformFilter(iface);
const WAVEFORMATEX *wfx = (WAVEFORMATEX *)mt->pbFormat;
HACMSTREAM drv;
MMRESULT res;
TRACE("(%p)\n", This);
if (!IsEqualGUID(&mt->majortype, &MEDIATYPE_Audio) || !is_audio_subtype(&mt->subtype)
|| !IsEqualGUID(&mt->formattype, &FORMAT_WaveFormatEx) || !wfx
|| wfx->wFormatTag == WAVE_FORMAT_PCM || wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
return VFW_E_TYPE_NOT_ACCEPTED;
if (dir != PINDIR_INPUT)
return S_OK;
CopyMediaType(&filter->tf.pmt, mt);
filter->tf.pmt.subtype.Data1 = WAVE_FORMAT_PCM;
filter->pWfOut = (WAVEFORMATEX *)filter->tf.pmt.pbFormat;
filter->pWfOut->wFormatTag = WAVE_FORMAT_PCM;
filter->pWfOut->wBitsPerSample = 16;
filter->pWfOut->nBlockAlign = filter->pWfOut->wBitsPerSample * filter->pWfOut->nChannels / 8;
filter->pWfOut->cbSize = 0;
filter->pWfOut->nAvgBytesPerSec = filter->pWfOut->nChannels * filter->pWfOut->nSamplesPerSec
* (filter->pWfOut->wBitsPerSample / 8);
if (!(res = acmStreamOpen(&drv, NULL, This->pWfIn, This->pWfOut, NULL, 0, 0, 0)))
if ((res = acmStreamOpen(&drv, NULL, (WAVEFORMATEX *)wfx, filter->pWfOut, NULL, 0, 0, 0)))
{
This->has = drv;
TRACE("Connection accepted\n");
return S_OK;
ERR("Failed to open stream, error %u.\n", res);
FreeMediaType(&filter->tf.pmt);
return VFW_E_TYPE_NOT_ACCEPTED;
}
FIXME("acmStreamOpen returned %d\n", res);
TRACE("Unable to find a suitable ACM decompressor\n");
return VFW_E_TYPE_NOT_ACCEPTED;
filter->has = drv;
return S_OK;
}
static HRESULT WINAPI ACMWrapper_BreakConnect(TransformFilter *tf, PIN_DIRECTION dir)
@ -341,18 +298,10 @@ static HRESULT WINAPI ACMWrapper_DecideBufferSize(TransformFilter *tf, IMemAlloc
}
static const TransformFilterFuncTable ACMWrapper_FuncsTable = {
ACMWrapper_DecideBufferSize,
NULL,
ACMWrapper_Receive,
NULL,
NULL,
ACMWrapper_SetMediaType,
ACMWrapper_CompleteConnect,
ACMWrapper_BreakConnect,
NULL,
NULL,
NULL,
NULL
.pfnDecideBufferSize = ACMWrapper_DecideBufferSize,
.pfnReceive = ACMWrapper_Receive,
.transform_connect_sink = acm_wrapper_connect_sink,
.pfnBreakConnect = ACMWrapper_BreakConnect,
};
HRESULT ACMWrapper_create(IUnknown *outer, void **out)

View File

@ -210,16 +210,11 @@ static HRESULT WINAPI AVIDec_StopStreaming(TransformFilter* pTransformFilter)
return S_OK;
}
static HRESULT WINAPI AVIDec_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE * pmt)
static HRESULT avi_dec_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *pmt)
{
AVIDecImpl* This = impl_from_TransformFilter(tf);
HRESULT hr = VFW_E_TYPE_NOT_ACCEPTED;
TRACE("(%p)->(%p)\n", This, pmt);
if (dir != PINDIR_INPUT)
return S_OK;
/* Check root (GUID w/o FOURCC) */
if ((IsEqualIID(&pmt->majortype, &MEDIATYPE_Video)) &&
(!memcmp(((const char *)&pmt->subtype)+4, ((const char *)&MEDIATYPE_Video)+4, sizeof(GUID)-4)))
@ -310,15 +305,6 @@ failed:
return hr;
}
static HRESULT WINAPI AVIDec_CompleteConnect(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin)
{
AVIDecImpl* This = impl_from_TransformFilter(tf);
TRACE("(%p)\n", This);
return S_OK;
}
static HRESULT WINAPI AVIDec_BreakConnect(TransformFilter *tf, PIN_DIRECTION dir)
{
AVIDecImpl *This = impl_from_TransformFilter(tf);
@ -357,19 +343,14 @@ static HRESULT WINAPI AVIDec_DecideBufferSize(TransformFilter *tf, IMemAllocator
}
static const TransformFilterFuncTable AVIDec_FuncsTable = {
AVIDec_DecideBufferSize,
AVIDec_StartStreaming,
AVIDec_Receive,
AVIDec_StopStreaming,
NULL,
AVIDec_SetMediaType,
AVIDec_CompleteConnect,
AVIDec_BreakConnect,
NULL,
NULL,
AVIDec_EndFlush,
NULL,
AVIDec_NotifyDrop
.pfnDecideBufferSize = AVIDec_DecideBufferSize,
.pfnStartStreaming = AVIDec_StartStreaming,
.pfnReceive = AVIDec_Receive,
.pfnStopStreaming = AVIDec_StopStreaming,
.transform_connect_sink = avi_dec_connect_sink,
.pfnBreakConnect = AVIDec_BreakConnect,
.pfnEndFlush = AVIDec_EndFlush,
.pfnNotify = AVIDec_NotifyDrop,
};
HRESULT AVIDec_create(IUnknown *outer, void **out)

View File

@ -405,11 +405,8 @@ static HRESULT WINAPI TransformFilter_InputPin_ReceiveConnection(IPin * iface, I
TRACE("(%p)->(%p, %p)\n", iface, pReceivePin, pmt);
strmbase_dump_media_type(pmt);
if (pTransform->pFuncsTable->pfnSetMediaType)
hr = pTransform->pFuncsTable->pfnSetMediaType(pTransform, PINDIR_INPUT, pmt);
if (SUCCEEDED(hr) && pTransform->pFuncsTable->pfnCompleteConnect)
hr = pTransform->pFuncsTable->pfnCompleteConnect(pTransform, PINDIR_INPUT, pReceivePin);
if (pTransform->pFuncsTable->transform_connect_sink)
hr = pTransform->pFuncsTable->transform_connect_sink(pTransform, pmt);
if (SUCCEEDED(hr))
{

View File

@ -516,7 +516,7 @@ static HRESULT WINAPI Gstreamer_Mp3_QueryConnect(TransformFilter *iface, const A
return S_OK;
}
static HRESULT WINAPI Gstreamer_Mp3_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE *amt)
static HRESULT mp3_decoder_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *amt)
{
GstTfImpl *This = (GstTfImpl*)tf;
GstCaps *capsin, *capsout;
@ -525,13 +525,8 @@ static HRESULT WINAPI Gstreamer_Mp3_SetMediaType(TransformFilter *tf, PIN_DIRECT
HRESULT hr;
int layer;
TRACE("%p 0x%x %p\n", This, dir, amt);
mark_wine_thread();
if (dir != PINDIR_INPUT)
return S_OK;
if (Gstreamer_Mp3_QueryConnect(&This->tf, amt) == S_FALSE || !amt->pbFormat)
return VFW_E_TYPE_NOT_ACCEPTED;
@ -588,26 +583,19 @@ static HRESULT WINAPI Gstreamer_Mp3_SetMediaType(TransformFilter *tf, PIN_DIRECT
return hr;
}
static HRESULT WINAPI Gstreamer_Mp3_ConnectInput(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin)
{
TRACE("%p 0x%x %p\n", tf, dir, pin);
return S_OK;
}
static const TransformFilterFuncTable Gstreamer_Mp3_vtbl = {
Gstreamer_transform_DecideBufferSize,
Gstreamer_transform_ProcessBegin,
Gstreamer_transform_ProcessData,
Gstreamer_transform_ProcessEnd,
Gstreamer_Mp3_QueryConnect,
Gstreamer_Mp3_SetMediaType,
Gstreamer_Mp3_ConnectInput,
Gstreamer_transform_Cleanup,
Gstreamer_transform_EndOfStream,
Gstreamer_transform_BeginFlush,
Gstreamer_transform_EndFlush,
Gstreamer_transform_NewSegment,
Gstreamer_transform_QOS
.pfnDecideBufferSize = Gstreamer_transform_DecideBufferSize,
.pfnStartStreaming = Gstreamer_transform_ProcessBegin,
.pfnReceive = Gstreamer_transform_ProcessData,
.pfnStopStreaming = Gstreamer_transform_ProcessEnd,
.pfnCheckInputType = Gstreamer_Mp3_QueryConnect,
.transform_connect_sink = mp3_decoder_connect_sink,
.pfnBreakConnect = Gstreamer_transform_Cleanup,
.pfnEndOfStream = Gstreamer_transform_EndOfStream,
.pfnBeginFlush = Gstreamer_transform_BeginFlush,
.pfnEndFlush = Gstreamer_transform_EndFlush,
.pfnNewSegment = Gstreamer_transform_NewSegment,
.pfnNotify = Gstreamer_transform_QOS,
};
IUnknown * CALLBACK Gstreamer_Mp3_create(IUnknown *punkouter, HRESULT *phr)
@ -664,13 +652,7 @@ static HRESULT WINAPI Gstreamer_YUV_QueryConnect(TransformFilter *iface, const A
}
}
static HRESULT WINAPI Gstreamer_YUV_ConnectInput(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin)
{
TRACE("%p 0x%x %p\n", tf, dir, pin);
return S_OK;
}
static HRESULT WINAPI Gstreamer_YUV2RGB_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE *amt)
static HRESULT yuv_to_rgb_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *amt)
{
GstTfImpl *This = (GstTfImpl*)tf;
GstCaps *capsin, *capsout;
@ -679,13 +661,8 @@ static HRESULT WINAPI Gstreamer_YUV2RGB_SetMediaType(TransformFilter *tf, PIN_DI
int avgtime;
LONG width, height;
TRACE("%p 0x%x %p\n", This, dir, amt);
mark_wine_thread();
if (dir != PINDIR_INPUT)
return S_OK;
if (Gstreamer_YUV_QueryConnect(&This->tf, amt) == S_FALSE || !amt->pbFormat)
return E_FAIL;
@ -738,19 +715,18 @@ static HRESULT WINAPI Gstreamer_YUV2RGB_SetMediaType(TransformFilter *tf, PIN_DI
}
static const TransformFilterFuncTable Gstreamer_YUV2RGB_vtbl = {
Gstreamer_transform_DecideBufferSize,
Gstreamer_transform_ProcessBegin,
Gstreamer_transform_ProcessData,
Gstreamer_transform_ProcessEnd,
Gstreamer_YUV_QueryConnect,
Gstreamer_YUV2RGB_SetMediaType,
Gstreamer_YUV_ConnectInput,
Gstreamer_transform_Cleanup,
Gstreamer_transform_EndOfStream,
Gstreamer_transform_BeginFlush,
Gstreamer_transform_EndFlush,
Gstreamer_transform_NewSegment,
Gstreamer_transform_QOS
.pfnDecideBufferSize = Gstreamer_transform_DecideBufferSize,
.pfnStartStreaming = Gstreamer_transform_ProcessBegin,
.pfnReceive = Gstreamer_transform_ProcessData,
.pfnStopStreaming = Gstreamer_transform_ProcessEnd,
.pfnCheckInputType = Gstreamer_YUV_QueryConnect,
.transform_connect_sink = yuv_to_rgb_connect_sink,
.pfnBreakConnect = Gstreamer_transform_Cleanup,
.pfnEndOfStream = Gstreamer_transform_EndOfStream,
.pfnBeginFlush = Gstreamer_transform_BeginFlush,
.pfnEndFlush = Gstreamer_transform_EndFlush,
.pfnNewSegment = Gstreamer_transform_NewSegment,
.pfnNotify = Gstreamer_transform_QOS,
};
IUnknown * CALLBACK Gstreamer_YUV2RGB_create(IUnknown *punkouter, HRESULT *phr)
@ -772,7 +748,7 @@ IUnknown * CALLBACK Gstreamer_YUV2RGB_create(IUnknown *punkouter, HRESULT *phr)
return obj;
}
static HRESULT WINAPI Gstreamer_YUV2ARGB_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE *amt)
static HRESULT yuv_to_argb_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *amt)
{
GstTfImpl *This = (GstTfImpl*)tf;
GstCaps *capsin, *capsout;
@ -781,13 +757,8 @@ static HRESULT WINAPI Gstreamer_YUV2ARGB_SetMediaType(TransformFilter *tf, PIN_D
int avgtime;
LONG width, height;
TRACE("%p 0x%x %p\n", This, dir, amt);
mark_wine_thread();
if (dir != PINDIR_INPUT)
return S_OK;
if (Gstreamer_YUV_QueryConnect(&This->tf, amt) == S_FALSE || !amt->pbFormat)
return E_FAIL;
@ -840,19 +811,18 @@ static HRESULT WINAPI Gstreamer_YUV2ARGB_SetMediaType(TransformFilter *tf, PIN_D
}
static const TransformFilterFuncTable Gstreamer_YUV2ARGB_vtbl = {
Gstreamer_transform_DecideBufferSize,
Gstreamer_transform_ProcessBegin,
Gstreamer_transform_ProcessData,
Gstreamer_transform_ProcessEnd,
Gstreamer_YUV_QueryConnect,
Gstreamer_YUV2ARGB_SetMediaType,
Gstreamer_YUV_ConnectInput,
Gstreamer_transform_Cleanup,
Gstreamer_transform_EndOfStream,
Gstreamer_transform_BeginFlush,
Gstreamer_transform_EndFlush,
Gstreamer_transform_NewSegment,
Gstreamer_transform_QOS
.pfnDecideBufferSize = Gstreamer_transform_DecideBufferSize,
.pfnStartStreaming = Gstreamer_transform_ProcessBegin,
.pfnReceive = Gstreamer_transform_ProcessData,
.pfnStopStreaming = Gstreamer_transform_ProcessEnd,
.pfnCheckInputType = Gstreamer_YUV_QueryConnect,
.transform_connect_sink = yuv_to_argb_connect_sink,
.pfnBreakConnect = Gstreamer_transform_Cleanup,
.pfnEndOfStream = Gstreamer_transform_EndOfStream,
.pfnBeginFlush = Gstreamer_transform_BeginFlush,
.pfnEndFlush = Gstreamer_transform_EndFlush,
.pfnNewSegment = Gstreamer_transform_NewSegment,
.pfnNotify = Gstreamer_transform_QOS,
};
IUnknown * CALLBACK Gstreamer_YUV2ARGB_create(IUnknown *punkouter, HRESULT *phr)
@ -886,13 +856,7 @@ static HRESULT WINAPI Gstreamer_AudioConvert_QueryConnect(TransformFilter *iface
return S_OK;
}
static HRESULT WINAPI Gstreamer_AudioConvert_ConnectInput(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin)
{
TRACE("%p 0x%x %p\n", tf, dir, pin);
return S_OK;
}
static HRESULT WINAPI Gstreamer_AudioConvert_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE *amt)
static HRESULT audio_converter_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *amt)
{
GstTfImpl *This = (GstTfImpl*)tf;
GstCaps *capsin, *capsout;
@ -905,13 +869,8 @@ static HRESULT WINAPI Gstreamer_AudioConvert_SetMediaType(TransformFilter *tf, P
BOOL inisfloat = FALSE;
int indepth;
TRACE("%p 0x%x %p\n", This, dir, amt);
mark_wine_thread();
if (dir != PINDIR_INPUT)
return S_OK;
if (Gstreamer_AudioConvert_QueryConnect(&This->tf, amt) == S_FALSE || !amt->pbFormat)
return E_FAIL;
@ -972,19 +931,18 @@ static HRESULT WINAPI Gstreamer_AudioConvert_SetMediaType(TransformFilter *tf, P
}
static const TransformFilterFuncTable Gstreamer_AudioConvert_vtbl = {
Gstreamer_transform_DecideBufferSize,
Gstreamer_transform_ProcessBegin,
Gstreamer_transform_ProcessData,
Gstreamer_transform_ProcessEnd,
Gstreamer_AudioConvert_QueryConnect,
Gstreamer_AudioConvert_SetMediaType,
Gstreamer_AudioConvert_ConnectInput,
Gstreamer_transform_Cleanup,
Gstreamer_transform_EndOfStream,
Gstreamer_transform_BeginFlush,
Gstreamer_transform_EndFlush,
Gstreamer_transform_NewSegment,
Gstreamer_transform_QOS
.pfnDecideBufferSize = Gstreamer_transform_DecideBufferSize,
.pfnStartStreaming = Gstreamer_transform_ProcessBegin,
.pfnReceive = Gstreamer_transform_ProcessData,
.pfnStopStreaming = Gstreamer_transform_ProcessEnd,
.pfnCheckInputType = Gstreamer_AudioConvert_QueryConnect,
.transform_connect_sink = audio_converter_connect_sink,
.pfnBreakConnect = Gstreamer_transform_Cleanup,
.pfnEndOfStream = Gstreamer_transform_EndOfStream,
.pfnBeginFlush = Gstreamer_transform_BeginFlush,
.pfnEndFlush = Gstreamer_transform_EndFlush,
.pfnNewSegment = Gstreamer_transform_NewSegment,
.pfnNotify = Gstreamer_transform_QOS,
};
IUnknown * CALLBACK Gstreamer_AudioConvert_create(IUnknown *punkouter, HRESULT *phr)

View File

@ -336,7 +336,7 @@ static HRESULT WINAPI QTVDecoder_StopStreaming(TransformFilter* pTransformFilter
return S_OK;
}
static HRESULT WINAPI QTVDecoder_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE * pmt)
static HRESULT video_decoder_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *pmt)
{
QTVDecoderImpl* This = impl_from_TransformFilter(tf);
HRESULT hr = VFW_E_TYPE_NOT_ACCEPTED;
@ -344,11 +344,6 @@ static HRESULT WINAPI QTVDecoder_SetMediaType(TransformFilter *tf, PIN_DIRECTION
AM_MEDIA_TYPE *outpmt = &This->tf.pmt;
CFNumberRef n = NULL;
TRACE("(%p)->(%p)\n", This, pmt);
if (dir != PINDIR_INPUT)
return S_OK;
FreeMediaType(outpmt);
CopyMediaType(outpmt, pmt);
@ -502,18 +497,12 @@ static HRESULT WINAPI QTVDecoder_DecideBufferSize(TransformFilter *tf, IMemAlloc
}
static const TransformFilterFuncTable QTVDecoder_FuncsTable = {
QTVDecoder_DecideBufferSize,
QTVDecoder_StartStreaming,
QTVDecoder_Receive,
QTVDecoder_StopStreaming,
NULL,
QTVDecoder_SetMediaType,
NULL,
QTVDecoder_BreakConnect,
NULL,
NULL,
NULL,
NULL
.pfnDecideBufferSize = QTVDecoder_DecideBufferSize,
.pfnStartStreaming = QTVDecoder_StartStreaming,
.pfnReceive = QTVDecoder_Receive,
.pfnStopStreaming = QTVDecoder_StopStreaming,
.transform_connect_sink = video_decoder_connect_sink,
.pfnBreakConnect = QTVDecoder_BreakConnect,
};
IUnknown * CALLBACK QTVDecoder_create(IUnknown *outer, HRESULT* phr)

View File

@ -197,9 +197,7 @@ typedef HRESULT (WINAPI *TransformFilter_DecideBufferSize) (TransformFilter *ifa
typedef HRESULT (WINAPI *TransformFilter_StartStreaming) (TransformFilter *iface);
typedef HRESULT (WINAPI *TransformFilter_StopStreaming) (TransformFilter *iface);
typedef HRESULT (WINAPI *TransformFilter_Receive) (TransformFilter* iface, IMediaSample* pIn);
typedef HRESULT (WINAPI *TransformFilter_CompleteConnect) (TransformFilter *iface, PIN_DIRECTION dir, IPin *pPin);
typedef HRESULT (WINAPI *TransformFilter_BreakConnect) (TransformFilter *iface, PIN_DIRECTION dir);
typedef HRESULT (WINAPI *TransformFilter_SetMediaType) (TransformFilter *iface, PIN_DIRECTION dir, const AM_MEDIA_TYPE *pMediaType);
typedef HRESULT (WINAPI *TransformFilter_CheckInputType) (TransformFilter *iface, const AM_MEDIA_TYPE *pMediaType);
typedef HRESULT (WINAPI *TransformFilter_EndOfStream) (TransformFilter *iface);
typedef HRESULT (WINAPI *TransformFilter_BeginFlush) (TransformFilter *iface);
@ -216,8 +214,7 @@ typedef struct TransformFilterFuncTable {
TransformFilter_Receive pfnReceive;
TransformFilter_StopStreaming pfnStopStreaming;
TransformFilter_CheckInputType pfnCheckInputType;
TransformFilter_SetMediaType pfnSetMediaType;
TransformFilter_CompleteConnect pfnCompleteConnect;
HRESULT (*transform_connect_sink)(TransformFilter *filter, const AM_MEDIA_TYPE *mt);
TransformFilter_BreakConnect pfnBreakConnect;
TransformFilter_EndOfStream pfnEndOfStream;
TransformFilter_BeginFlush pfnBeginFlush;