qasf/dmowrapper: Implement source connection.
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
6fa6ef90a4
commit
c1b7a334f5
|
@ -166,10 +166,56 @@ static HRESULT dmo_wrapper_source_get_media_type(struct strmbase_pin *iface, uns
|
|||
return hr == S_OK ? S_OK : VFW_S_NO_MORE_ITEMS;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI dmo_wrapper_source_DecideBufferSize(struct strmbase_source *iface,
|
||||
IMemAllocator *allocator, ALLOCATOR_PROPERTIES *props)
|
||||
{
|
||||
struct dmo_wrapper *filter = impl_from_strmbase_filter(iface->pin.filter);
|
||||
DWORD index = impl_source_from_strmbase_pin(&iface->pin) - filter->sources;
|
||||
ALLOCATOR_PROPERTIES ret_props;
|
||||
DWORD size = 0, alignment = 0;
|
||||
IMediaObject *dmo;
|
||||
HRESULT hr;
|
||||
|
||||
IUnknown_QueryInterface(filter->dmo, &IID_IMediaObject, (void **)&dmo);
|
||||
|
||||
if (SUCCEEDED(hr = IMediaObject_SetOutputType(dmo, index,
|
||||
(const DMO_MEDIA_TYPE *)&iface->pin.mt, 0)))
|
||||
hr = IMediaObject_GetOutputSizeInfo(dmo, index, &size, &alignment);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
props->cBuffers = max(props->cBuffers, 1);
|
||||
props->cbBuffer = max(max(props->cbBuffer, size), 16384);
|
||||
props->cbAlign = max(props->cbAlign, alignment);
|
||||
hr = IMemAllocator_SetProperties(allocator, props, &ret_props);
|
||||
}
|
||||
|
||||
IMediaObject_Release(dmo);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static void dmo_wrapper_source_disconnect(struct strmbase_source *iface)
|
||||
{
|
||||
struct dmo_wrapper *filter = impl_from_strmbase_filter(iface->pin.filter);
|
||||
IMediaObject *dmo;
|
||||
|
||||
IUnknown_QueryInterface(filter->dmo, &IID_IMediaObject, (void **)&dmo);
|
||||
|
||||
IMediaObject_SetOutputType(dmo, impl_source_from_strmbase_pin(&iface->pin) - filter->sources,
|
||||
NULL, DMO_SET_TYPEF_CLEAR);
|
||||
|
||||
IMediaObject_Release(dmo);
|
||||
}
|
||||
|
||||
static const struct strmbase_source_ops source_ops =
|
||||
{
|
||||
.base.pin_query_accept = dmo_wrapper_source_query_accept,
|
||||
.base.pin_get_media_type = dmo_wrapper_source_get_media_type,
|
||||
.pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection,
|
||||
.pfnDecideAllocator = BaseOutputPinImpl_DecideAllocator,
|
||||
.pfnDecideBufferSize = dmo_wrapper_source_DecideBufferSize,
|
||||
.source_disconnect = dmo_wrapper_source_disconnect,
|
||||
};
|
||||
|
||||
static inline struct dmo_wrapper *impl_from_IDMOWrapperFilter(IDMOWrapperFilter *iface)
|
||||
|
|
|
@ -61,10 +61,13 @@ static const IMediaObjectVtbl dmo_vtbl;
|
|||
static IMediaObject testdmo = {&dmo_vtbl};
|
||||
static IUnknown *testdmo_outer_unk;
|
||||
static LONG testdmo_refcount = 1;
|
||||
static AM_MEDIA_TYPE testdmo_input_mt;
|
||||
static BOOL testdmo_input_mt_set;
|
||||
static AM_MEDIA_TYPE testdmo_input_mt, testdmo_output_mt;
|
||||
static BOOL testdmo_input_mt_set, testdmo_output_mt_set;
|
||||
|
||||
static HRESULT testdmo_GetInputSizeInfo_hr = E_NOTIMPL;
|
||||
static HRESULT testdmo_GetOutputSizeInfo_hr = S_OK;
|
||||
static DWORD testdmo_output_size = 123;
|
||||
static DWORD testdmo_output_alignment = 1;
|
||||
|
||||
static HRESULT WINAPI dmo_inner_QueryInterface(IUnknown *iface, REFIID iid, void **out)
|
||||
{
|
||||
|
@ -183,6 +186,13 @@ static HRESULT WINAPI dmo_SetOutputType(IMediaObject *iface, DWORD index, const
|
|||
strmbase_dump_media_type((AM_MEDIA_TYPE *)type);
|
||||
if (flags & DMO_SET_TYPEF_TEST_ONLY)
|
||||
return type->lSampleSize == 321 ? S_OK : S_FALSE;
|
||||
if (flags & DMO_SET_TYPEF_CLEAR)
|
||||
{
|
||||
testdmo_output_mt_set = FALSE;
|
||||
return S_OK;
|
||||
}
|
||||
MoCopyMediaType((DMO_MEDIA_TYPE *)&testdmo_output_mt, type);
|
||||
testdmo_output_mt_set = TRUE;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -210,8 +220,10 @@ static HRESULT WINAPI dmo_GetInputSizeInfo(IMediaObject *iface, DWORD index,
|
|||
|
||||
static HRESULT WINAPI dmo_GetOutputSizeInfo(IMediaObject *iface, DWORD index, DWORD *size, DWORD *alignment)
|
||||
{
|
||||
ok(0, "Unexpected call.\n");
|
||||
return E_NOTIMPL;
|
||||
if (winetest_debug > 1) trace("GetOutputSizeInfo(%u)\n", index);
|
||||
*size = testdmo_output_size;
|
||||
*alignment = testdmo_output_alignment;
|
||||
return testdmo_GetOutputSizeInfo_hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI dmo_GetInputMaxLatency(IMediaObject *iface, DWORD index, REFERENCE_TIME *latency)
|
||||
|
@ -1137,6 +1149,71 @@ static void test_sink_allocator(IMemInputPin *input)
|
|||
IMemAllocator_Release(ret_allocator);
|
||||
}
|
||||
|
||||
static void test_source_allocator(IFilterGraph2 *graph, IPin *source, struct testfilter *testsink)
|
||||
{
|
||||
ALLOCATOR_PROPERTIES props, req_props = {2, 30000, 32, 0};
|
||||
IMemAllocator *allocator;
|
||||
HRESULT hr;
|
||||
|
||||
hr = IFilterGraph2_ConnectDirect(graph, source, &testsink->sink.pin.IPin_iface, &mt2);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
ok(!!testsink->sink.pAllocator, "Expected an allocator.\n");
|
||||
hr = IMemAllocator_GetProperties(testsink->sink.pAllocator, &props);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(props.cBuffers == 1, "Got %d buffers.\n", props.cBuffers);
|
||||
ok(props.cbBuffer == 16384, "Got size %d.\n", props.cbBuffer);
|
||||
ok(props.cbAlign == 1, "Got alignment %d.\n", props.cbAlign);
|
||||
ok(!props.cbPrefix, "Got prefix %d.\n", props.cbPrefix);
|
||||
|
||||
IFilterGraph2_Disconnect(graph, source);
|
||||
IFilterGraph2_Disconnect(graph, &testsink->sink.pin.IPin_iface);
|
||||
|
||||
testdmo_output_alignment = 16;
|
||||
testdmo_output_size = 20000;
|
||||
|
||||
hr = IFilterGraph2_ConnectDirect(graph, source, &testsink->sink.pin.IPin_iface, &mt2);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
ok(!!testsink->sink.pAllocator, "Expected an allocator.\n");
|
||||
hr = IMemAllocator_GetProperties(testsink->sink.pAllocator, &props);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(props.cBuffers == 1, "Got %d buffers.\n", props.cBuffers);
|
||||
ok(props.cbBuffer == 20000, "Got size %d.\n", props.cbBuffer);
|
||||
ok(props.cbAlign == 16, "Got alignment %d.\n", props.cbAlign);
|
||||
ok(!props.cbPrefix, "Got prefix %d.\n", props.cbPrefix);
|
||||
|
||||
IFilterGraph2_Disconnect(graph, source);
|
||||
IFilterGraph2_Disconnect(graph, &testsink->sink.pin.IPin_iface);
|
||||
|
||||
testdmo_GetOutputSizeInfo_hr = E_NOTIMPL;
|
||||
hr = IFilterGraph2_ConnectDirect(graph, source, &testsink->sink.pin.IPin_iface, &mt2);
|
||||
ok(hr == E_NOTIMPL, "Got hr %#x.\n", hr);
|
||||
testdmo_GetOutputSizeInfo_hr = S_OK;
|
||||
|
||||
CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER,
|
||||
&IID_IMemAllocator, (void **)&allocator);
|
||||
testsink->sink.pAllocator = allocator;
|
||||
|
||||
hr = IMemAllocator_SetProperties(allocator, &req_props, &props);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IFilterGraph2_ConnectDirect(graph, source, &testsink->sink.pin.IPin_iface, &mt2);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
ok(testsink->sink.pAllocator == allocator, "Expected an allocator.\n");
|
||||
hr = IMemAllocator_GetProperties(testsink->sink.pAllocator, &props);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(props.cBuffers == 1, "Got %d buffers.\n", props.cBuffers);
|
||||
ok(props.cbBuffer == 20000, "Got size %d.\n", props.cbBuffer);
|
||||
ok(props.cbAlign == 16, "Got alignment %d.\n", props.cbAlign);
|
||||
ok(!props.cbPrefix, "Got prefix %d.\n", props.cbPrefix);
|
||||
|
||||
IFilterGraph2_Disconnect(graph, source);
|
||||
IFilterGraph2_Disconnect(graph, &testsink->sink.pin.IPin_iface);
|
||||
|
||||
}
|
||||
|
||||
static void test_connect_pin(void)
|
||||
{
|
||||
AM_MEDIA_TYPE req_mt =
|
||||
|
@ -1146,20 +1223,23 @@ static void test_connect_pin(void)
|
|||
.formattype = FORMAT_None,
|
||||
};
|
||||
IBaseFilter *filter = create_dmo_wrapper();
|
||||
struct testfilter testsource;
|
||||
struct testfilter testsource, testsink;
|
||||
IPin *sink, *source, *peer;
|
||||
IMemInputPin *meminput;
|
||||
IFilterGraph2 *graph;
|
||||
IPin *sink, *peer;
|
||||
AM_MEDIA_TYPE mt;
|
||||
HRESULT hr;
|
||||
ULONG ref;
|
||||
|
||||
testfilter_init(&testsource);
|
||||
testfilter_init(&testsink);
|
||||
CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
|
||||
&IID_IFilterGraph2, (void **)&graph);
|
||||
IFilterGraph2_AddFilter(graph, &testsource.filter.IBaseFilter_iface, L"source");
|
||||
IFilterGraph2_AddFilter(graph, &testsink.filter.IBaseFilter_iface, L"sink");
|
||||
IFilterGraph2_AddFilter(graph, filter, L"DMO wrapper");
|
||||
IBaseFilter_FindPin(filter, L"in0", &sink);
|
||||
IBaseFilter_FindPin(filter, L"out0", &source);
|
||||
IPin_QueryInterface(sink, &IID_IMemInputPin, (void **)&meminput);
|
||||
|
||||
/* Test sink connection. */
|
||||
|
@ -1194,6 +1274,149 @@ static void test_connect_pin(void)
|
|||
|
||||
test_sink_allocator(meminput);
|
||||
|
||||
/* Test source connection. */
|
||||
peer = (IPin *)0xdeadbeef;
|
||||
hr = IPin_ConnectedTo(source, &peer);
|
||||
ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#x.\n", hr);
|
||||
ok(!peer, "Got peer %p.\n", peer);
|
||||
|
||||
hr = IPin_ConnectionMediaType(source, &mt);
|
||||
ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#x.\n", hr);
|
||||
|
||||
ok(!testdmo_output_mt_set, "Output type should not be set.\n");
|
||||
|
||||
/* Exact connection. */
|
||||
|
||||
req_mt = mt2;
|
||||
hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IPin_ConnectedTo(source, &peer);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(peer == &testsink.sink.pin.IPin_iface, "Got peer %p.\n", peer);
|
||||
IPin_Release(peer);
|
||||
|
||||
hr = IPin_ConnectionMediaType(source, &mt);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(compare_media_types(&mt, &req_mt), "Media types didn't match.\n");
|
||||
|
||||
ok(testdmo_output_mt_set, "Ouput type should be set.\n");
|
||||
ok(compare_media_types(&testdmo_output_mt, &req_mt), "Media types didn't match.\n");
|
||||
|
||||
hr = IFilterGraph2_Disconnect(graph, source);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
hr = IFilterGraph2_Disconnect(graph, source);
|
||||
ok(hr == S_FALSE, "Got hr %#x.\n", hr);
|
||||
ok(testsink.sink.pin.peer == source, "Got peer %p.\n", testsink.sink.pin.peer);
|
||||
IFilterGraph2_Disconnect(graph, &testsink.sink.pin.IPin_iface);
|
||||
|
||||
peer = (IPin *)0xdeadbeef;
|
||||
hr = IPin_ConnectedTo(source, &peer);
|
||||
ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#x.\n", hr);
|
||||
ok(!peer, "Got peer %p.\n", peer);
|
||||
|
||||
hr = IPin_ConnectionMediaType(source, &mt);
|
||||
ok(hr == VFW_E_NOT_CONNECTED, "Got hr %#x.\n", hr);
|
||||
|
||||
ok(!testdmo_output_mt_set, "Output type should not be set.\n");
|
||||
|
||||
req_mt.lSampleSize = 0;
|
||||
hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
|
||||
ok(hr == VFW_E_TYPE_NOT_ACCEPTED, "Got hr %#x.\n", hr);
|
||||
|
||||
/* Connection with wildcards. */
|
||||
|
||||
hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, NULL);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(compare_media_types(&testsink.sink.pin.mt, &mt2), "Media types didn't match.\n");
|
||||
ok(testdmo_output_mt_set, "Ouput type should be set.\n");
|
||||
ok(compare_media_types(&testdmo_output_mt, &mt2), "Media types didn't match.\n");
|
||||
IFilterGraph2_Disconnect(graph, source);
|
||||
IFilterGraph2_Disconnect(graph, &testsink.sink.pin.IPin_iface);
|
||||
|
||||
req_mt.majortype = GUID_NULL;
|
||||
hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(compare_media_types(&testsink.sink.pin.mt, &mt2), "Media types didn't match.\n");
|
||||
IFilterGraph2_Disconnect(graph, source);
|
||||
IFilterGraph2_Disconnect(graph, &testsink.sink.pin.IPin_iface);
|
||||
|
||||
req_mt.subtype = MEDIASUBTYPE_RGB32;
|
||||
hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
|
||||
ok(hr == VFW_E_NO_ACCEPTABLE_TYPES, "Got hr %#x.\n", hr);
|
||||
|
||||
req_mt.subtype = GUID_NULL;
|
||||
hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(compare_media_types(&testsink.sink.pin.mt, &mt2), "Media types didn't match.\n");
|
||||
IFilterGraph2_Disconnect(graph, source);
|
||||
IFilterGraph2_Disconnect(graph, &testsink.sink.pin.IPin_iface);
|
||||
|
||||
req_mt.formattype = FORMAT_WaveFormatEx;
|
||||
hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
|
||||
ok(hr == VFW_E_NO_ACCEPTABLE_TYPES, "Got hr %#x.\n", hr);
|
||||
|
||||
req_mt = mt2;
|
||||
req_mt.formattype = GUID_NULL;
|
||||
hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(compare_media_types(&testsink.sink.pin.mt, &mt2), "Media types didn't match.\n");
|
||||
IFilterGraph2_Disconnect(graph, source);
|
||||
IFilterGraph2_Disconnect(graph, &testsink.sink.pin.IPin_iface);
|
||||
|
||||
req_mt.subtype = MEDIASUBTYPE_RGB32;
|
||||
hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
|
||||
ok(hr == VFW_E_NO_ACCEPTABLE_TYPES, "Got hr %#x.\n", hr);
|
||||
|
||||
req_mt.subtype = GUID_NULL;
|
||||
hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(compare_media_types(&testsink.sink.pin.mt, &mt2), "Media types didn't match.\n");
|
||||
IFilterGraph2_Disconnect(graph, source);
|
||||
IFilterGraph2_Disconnect(graph, &testsink.sink.pin.IPin_iface);
|
||||
|
||||
req_mt.majortype = MEDIATYPE_Audio;
|
||||
hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
|
||||
ok(hr == VFW_E_NO_ACCEPTABLE_TYPES, "Got hr %#x.\n", hr);
|
||||
|
||||
mt = req_mt;
|
||||
testsink.sink_mt = &mt;
|
||||
hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, NULL);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(compare_media_types(&testsink.sink.pin.mt, &mt), "Media types didn't match.\n");
|
||||
IFilterGraph2_Disconnect(graph, source);
|
||||
IFilterGraph2_Disconnect(graph, &testsink.sink.pin.IPin_iface);
|
||||
|
||||
mt.lSampleSize = 1;
|
||||
hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
|
||||
ok(hr == VFW_E_NO_ACCEPTABLE_TYPES, "Got hr %#x.\n", hr);
|
||||
mt.lSampleSize = 321;
|
||||
|
||||
mt.majortype = mt.subtype = mt.formattype = GUID_NULL;
|
||||
req_mt = mt;
|
||||
hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(compare_media_types(&testsink.sink.pin.mt, &mt), "Media types didn't match.\n");
|
||||
IFilterGraph2_Disconnect(graph, source);
|
||||
IFilterGraph2_Disconnect(graph, &testsink.sink.pin.IPin_iface);
|
||||
|
||||
req_mt.majortype = mt2.majortype;
|
||||
hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
|
||||
ok(hr == VFW_E_NO_ACCEPTABLE_TYPES, "Got hr %#x.\n", hr);
|
||||
req_mt.majortype = GUID_NULL;
|
||||
|
||||
req_mt.subtype = mt2.subtype;
|
||||
hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
|
||||
ok(hr == VFW_E_NO_ACCEPTABLE_TYPES, "Got hr %#x.\n", hr);
|
||||
req_mt.subtype = GUID_NULL;
|
||||
|
||||
req_mt.formattype = mt2.formattype;
|
||||
hr = IFilterGraph2_ConnectDirect(graph, source, &testsink.sink.pin.IPin_iface, &req_mt);
|
||||
ok(hr == VFW_E_NO_ACCEPTABLE_TYPES, "Got hr %#x.\n", hr);
|
||||
req_mt.formattype = GUID_NULL;
|
||||
|
||||
testsink.sink_mt = NULL;
|
||||
|
||||
hr = IFilterGraph2_Disconnect(graph, sink);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
hr = IFilterGraph2_Disconnect(graph, sink);
|
||||
|
@ -1211,7 +1434,10 @@ static void test_connect_pin(void)
|
|||
|
||||
ok(!testdmo_input_mt_set, "Input type should not be set.\n");
|
||||
|
||||
test_source_allocator(graph, source, &testsink);
|
||||
|
||||
IPin_Release(sink);
|
||||
IPin_Release(source);
|
||||
IMemInputPin_Release(meminput);
|
||||
ref = IFilterGraph2_Release(graph);
|
||||
ok(!ref, "Got outstanding refcount %d.\n", ref);
|
||||
|
@ -1219,6 +1445,8 @@ static void test_connect_pin(void)
|
|||
ok(!ref, "Got outstanding refcount %d.\n", ref);
|
||||
ref = IBaseFilter_Release(&testsource.filter.IBaseFilter_iface);
|
||||
ok(!ref, "Got outstanding refcount %d.\n", ref);
|
||||
ref = IBaseFilter_Release(&testsink.filter.IBaseFilter_iface);
|
||||
ok(!ref, "Got outstanding refcount %d.\n", ref);
|
||||
}
|
||||
|
||||
START_TEST(dmowrapper)
|
||||
|
|
|
@ -552,6 +552,9 @@ static HRESULT WINAPI source_Disconnect(IPin *iface)
|
|||
return VFW_E_NOT_STOPPED;
|
||||
}
|
||||
|
||||
if (This->pFuncsTable->source_disconnect)
|
||||
This->pFuncsTable->source_disconnect(This);
|
||||
|
||||
if (This->pMemInputPin)
|
||||
{
|
||||
IMemInputPin_Release(This->pMemInputPin);
|
||||
|
|
|
@ -74,6 +74,8 @@ struct strmbase_source_ops
|
|||
BaseOutputPin_DecideBufferSize pfnDecideBufferSize;
|
||||
/* Required for BaseOutputPinImpl_AttemptConnection */
|
||||
BaseOutputPin_DecideAllocator pfnDecideAllocator;
|
||||
|
||||
void (*source_disconnect)(struct strmbase_source *pin);
|
||||
};
|
||||
|
||||
struct strmbase_sink
|
||||
|
|
Loading…
Reference in New Issue