Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/strmbase/pin.c | 19 +++++++++---------- include/wine/strmbase.h | 25 +++++++++++++------------ 2 files changed, 22 insertions(+), 22 deletions(-)
diff --git a/dlls/strmbase/pin.c b/dlls/strmbase/pin.c index 6b84c9d1f18..3df9e3e333c 100644 --- a/dlls/strmbase/pin.c +++ b/dlls/strmbase/pin.c @@ -57,7 +57,7 @@ static HRESULT enum_media_types_create(struct strmbase_pin *pin, IEnumMediaTypes object->pin = pin; IPin_AddRef(&pin->IPin_iface);
- while (pin->pFuncsTable->pin_get_media_type(pin, object->count, &mt) == S_OK) + while (pin->ops->pin_get_media_type(pin, object->count, &mt) == S_OK) { FreeMediaType(&mt); ++object->count; @@ -124,7 +124,7 @@ static HRESULT WINAPI enum_media_types_Next(IEnumMediaTypes *iface, ULONG count, for (i = 0; i < count; ++i) { if ((mts[i] = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)))) - hr = enummt->pin->pFuncsTable->pin_get_media_type(enummt->pin, enummt->index + i, mts[i]); + hr = enummt->pin->ops->pin_get_media_type(enummt->pin, enummt->index + i, mts[i]); else hr = E_OUTOFMEMORY; if (FAILED(hr)) @@ -169,7 +169,7 @@ static HRESULT WINAPI enum_media_types_Reset(IEnumMediaTypes *iface) TRACE("enummt %p.\n", enummt);
enummt->count = 0; - while (enummt->pin->pFuncsTable->pin_get_media_type(enummt->pin, enummt->count, &mt) == S_OK) + while (enummt->pin->ops->pin_get_media_type(enummt->pin, enummt->count, &mt) == S_OK) { FreeMediaType(&mt); ++enummt->count; @@ -267,8 +267,7 @@ static HRESULT WINAPI pin_QueryInterface(IPin *iface, REFIID iid, void **out)
*out = NULL;
- if (pin->pFuncsTable->pin_query_interface - && SUCCEEDED(hr = pin->pFuncsTable->pin_query_interface(pin, iid, out))) + if (pin->ops->pin_query_interface && SUCCEEDED(hr = pin->ops->pin_query_interface(pin, iid, out))) return hr;
if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IPin)) @@ -392,7 +391,7 @@ static HRESULT WINAPI pin_QueryAccept(IPin *iface, const AM_MEDIA_TYPE *mt) TRACE("pin %p %s:%s, mt %p.\n", pin, debugstr_w(pin->filter->name), debugstr_w(pin->name), mt); strmbase_dump_media_type(mt);
- return (pin->pFuncsTable->pin_query_accept(pin, mt) == S_OK ? S_OK : S_FALSE); + return (pin->ops->pin_query_accept(pin, mt) == S_OK ? S_OK : S_FALSE); }
static HRESULT WINAPI pin_EnumMediaTypes(IPin *iface, IEnumMediaTypes **enum_media_types) @@ -404,7 +403,7 @@ static HRESULT WINAPI pin_EnumMediaTypes(IPin *iface, IEnumMediaTypes **enum_med TRACE("pin %p %s:%s, enum_media_types %p.\n", pin, debugstr_w(pin->filter->name), debugstr_w(pin->name), enum_media_types);
- if (FAILED(hr = pin->pFuncsTable->pin_get_media_type(pin, 0, &mt))) + if (FAILED(hr = pin->ops->pin_get_media_type(pin, 0, &mt))) return hr; if (hr == S_OK) FreeMediaType(&mt); @@ -791,7 +790,7 @@ void strmbase_source_init(struct strmbase_source *pin, struct strmbase_filter *f pin->pin.filter = filter; pin->pin.dir = PINDIR_OUTPUT; lstrcpyW(pin->pin.name, name); - pin->pin.pFuncsTable = &func_table->base; + pin->pin.ops = &func_table->base; pin->pFuncsTable = func_table; }
@@ -844,7 +843,7 @@ static HRESULT WINAPI sink_ReceiveConnection(IPin *iface, IPin *pReceivePin, con if (This->pin.peer) hr = VFW_E_ALREADY_CONNECTED;
- if (SUCCEEDED(hr) && This->pin.pFuncsTable->pin_query_accept(&This->pin, pmt) != S_OK) + if (SUCCEEDED(hr) && This->pin.ops->pin_query_accept(&This->pin, pmt) != S_OK) hr = VFW_E_TYPE_NOT_ACCEPTED; /* FIXME: shouldn't we just map common errors onto * VFW_E_TYPE_NOT_ACCEPTED and pass the value on otherwise? */
@@ -1171,7 +1170,7 @@ void strmbase_sink_init(struct strmbase_sink *pin, struct strmbase_filter *filte pin->pin.filter = filter; pin->pin.dir = PINDIR_INPUT; lstrcpyW(pin->pin.name, name); - pin->pin.pFuncsTable = &func_table->base; + pin->pin.ops = &func_table->base; pin->pFuncsTable = func_table; pin->pAllocator = pin->preferred_allocator = allocator; if (pin->preferred_allocator) diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h index 965f6be401a..57ff0247084 100644 --- a/include/wine/strmbase.h +++ b/include/wine/strmbase.h @@ -39,16 +39,17 @@ struct strmbase_pin IPin *peer; AM_MEDIA_TYPE mt;
- const struct BasePinFuncTable* pFuncsTable; + const struct strmbase_pin_ops *ops; };
-typedef struct BasePinFuncTable { +struct strmbase_pin_ops +{ /* Required for QueryAccept(), Connect(), ReceiveConnection(). */ HRESULT (*pin_query_accept)(struct strmbase_pin *pin, const AM_MEDIA_TYPE *mt); /* Required for EnumMediaTypes(). */ HRESULT (*pin_get_media_type)(struct strmbase_pin *pin, unsigned int index, AM_MEDIA_TYPE *mt); HRESULT (*pin_query_interface)(struct strmbase_pin *pin, REFIID iid, void **out); -} BasePinFuncTable; +};
struct strmbase_source { @@ -65,14 +66,14 @@ typedef HRESULT (WINAPI *BaseOutputPin_DecideAllocator)(struct strmbase_source *
struct strmbase_source_ops { - BasePinFuncTable base; - - /* Required for Connect(). */ - BaseOutputPin_AttemptConnection pfnAttemptConnection; - /* Required for BaseOutputPinImpl_DecideAllocator */ - BaseOutputPin_DecideBufferSize pfnDecideBufferSize; - /* Required for BaseOutputPinImpl_AttemptConnection */ - BaseOutputPin_DecideAllocator pfnDecideAllocator; + struct strmbase_pin_ops base; + + /* Required for Connect(). */ + BaseOutputPin_AttemptConnection pfnAttemptConnection; + /* Required for BaseOutputPinImpl_DecideAllocator */ + BaseOutputPin_DecideBufferSize pfnDecideBufferSize; + /* Required for BaseOutputPinImpl_AttemptConnection */ + BaseOutputPin_DecideAllocator pfnDecideAllocator; };
struct strmbase_sink @@ -91,7 +92,7 @@ typedef HRESULT (WINAPI *BaseInputPin_Receive)(struct strmbase_sink *This, IMedi
struct strmbase_sink_ops { - BasePinFuncTable base; + struct strmbase_pin_ops base; BaseInputPin_Receive pfnReceive; HRESULT (*sink_connect)(struct strmbase_sink *pin, IPin *peer, const AM_MEDIA_TYPE *mt); void (*sink_disconnect)(struct strmbase_sink *pin);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/strmbase/pin.c | 127 +++++++++++++++++++------------------------- 1 file changed, 56 insertions(+), 71 deletions(-)
diff --git a/dlls/strmbase/pin.c b/dlls/strmbase/pin.c index 3df9e3e333c..44831d13f44 100644 --- a/dlls/strmbase/pin.c +++ b/dlls/strmbase/pin.c @@ -428,96 +428,81 @@ static inline struct strmbase_source *impl_source_from_IPin( IPin *iface ) return CONTAINING_RECORD(iface, struct strmbase_source, pin.IPin_iface); }
-static HRESULT WINAPI source_Connect(IPin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt) +static HRESULT WINAPI source_Connect(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt) { + struct strmbase_source *pin = impl_source_from_IPin(iface); + AM_MEDIA_TYPE *candidate; + IEnumMediaTypes *enummt; + ULONG count; HRESULT hr; - struct strmbase_source *This = impl_source_from_IPin(iface);
- TRACE("pin %p %s:%s, peer %p, mt %p.\n", This, debugstr_w(This->pin.filter->name), - debugstr_w(This->pin.name), pReceivePin, pmt); - strmbase_dump_media_type(pmt); + TRACE("pin %p %s:%s, peer %p, mt %p.\n", pin, debugstr_w(pin->pin.filter->name), + debugstr_w(pin->pin.name), peer, mt); + strmbase_dump_media_type(mt);
- if (!pReceivePin) + if (!peer) return E_POINTER;
/* If we try to connect to ourselves, we will definitely deadlock. * There are other cases where we could deadlock too, but this * catches the obvious case */ - assert(pReceivePin != iface); + assert(peer != iface);
- EnterCriticalSection(&This->pin.filter->csFilter); + EnterCriticalSection(&pin->pin.filter->csFilter); + + if (pin->pin.filter->state != State_Stopped) { - if (This->pin.filter->state != State_Stopped) - { - LeaveCriticalSection(&This->pin.filter->csFilter); - WARN("Filter is not stopped; returning VFW_E_NOT_STOPPED.\n"); - return VFW_E_NOT_STOPPED; - } + LeaveCriticalSection(&pin->pin.filter->csFilter); + WARN("Filter is not stopped; returning VFW_E_NOT_STOPPED.\n"); + return VFW_E_NOT_STOPPED; + }
- /* if we have been a specific type to connect with, then we can either connect - * with that or fail. We cannot choose different AM_MEDIA_TYPE */ - if (pmt && !IsEqualGUID(&pmt->majortype, &GUID_NULL) && !IsEqualGUID(&pmt->subtype, &GUID_NULL)) - hr = This->pFuncsTable->pfnAttemptConnection(This, pReceivePin, pmt); - else + if (mt && !IsEqualGUID(&mt->majortype, &GUID_NULL) && !IsEqualGUID(&mt->subtype, &GUID_NULL)) + { + hr = pin->pFuncsTable->pfnAttemptConnection(pin, peer, mt); + LeaveCriticalSection(&pin->pin.filter->csFilter); + return hr; + } + + if (SUCCEEDED(IPin_EnumMediaTypes(iface, &enummt))) + { + while (IEnumMediaTypes_Next(enummt, 1, &candidate, NULL) == S_OK) { - /* negotiate media type */ + if ((!mt || CompareMediaTypes(mt, candidate, TRUE)) + && pin->pFuncsTable->pfnAttemptConnection(pin, peer, candidate) == S_OK) + { + LeaveCriticalSection(&pin->pin.filter->csFilter); + DeleteMediaType(candidate); + IEnumMediaTypes_Release(enummt); + return S_OK; + } + DeleteMediaType(candidate); + }
- IEnumMediaTypes * pEnumCandidates; - AM_MEDIA_TYPE * pmtCandidate = NULL; /* Candidate media type */ + IEnumMediaTypes_Release(enummt); + }
- if (SUCCEEDED(hr = IPin_EnumMediaTypes(iface, &pEnumCandidates))) + if (SUCCEEDED(IPin_EnumMediaTypes(peer, &enummt))) + { + while (IEnumMediaTypes_Next(enummt, 1, &candidate, &count) == S_OK) + { + if ((!mt || CompareMediaTypes(mt, candidate, TRUE)) + && pin->pFuncsTable->pfnAttemptConnection(pin, peer, candidate) == S_OK) { - hr = VFW_E_NO_ACCEPTABLE_TYPES; /* Assume the worst, but set to S_OK if connected successfully */ - - /* try this filter's media types first */ - while (S_OK == IEnumMediaTypes_Next(pEnumCandidates, 1, &pmtCandidate, NULL)) - { - assert(pmtCandidate); - if (!IsEqualGUID(&FORMAT_None, &pmtCandidate->formattype) - && !IsEqualGUID(&GUID_NULL, &pmtCandidate->formattype)) - assert(pmtCandidate->pbFormat); - if ((!pmt || CompareMediaTypes(pmt, pmtCandidate, TRUE)) - && This->pFuncsTable->pfnAttemptConnection(This, pReceivePin, pmtCandidate) == S_OK) - { - hr = S_OK; - DeleteMediaType(pmtCandidate); - break; - } - DeleteMediaType(pmtCandidate); - pmtCandidate = NULL; - } - IEnumMediaTypes_Release(pEnumCandidates); + LeaveCriticalSection(&pin->pin.filter->csFilter); + DeleteMediaType(candidate); + IEnumMediaTypes_Release(enummt); + return S_OK; } + DeleteMediaType(candidate); + }
- /* then try receiver filter's media types */ - if (hr != S_OK && SUCCEEDED(hr = IPin_EnumMediaTypes(pReceivePin, &pEnumCandidates))) /* if we haven't already connected successfully */ - { - ULONG fetched; - - hr = VFW_E_NO_ACCEPTABLE_TYPES; /* Assume the worst, but set to S_OK if connected successfully */ - - while (S_OK == IEnumMediaTypes_Next(pEnumCandidates, 1, &pmtCandidate, &fetched)) - { - assert(pmtCandidate); - strmbase_dump_media_type(pmtCandidate); - if ((!pmt || CompareMediaTypes(pmt, pmtCandidate, TRUE)) - && This->pFuncsTable->pfnAttemptConnection(This, pReceivePin, pmtCandidate) == S_OK) - { - hr = S_OK; - DeleteMediaType(pmtCandidate); - break; - } - DeleteMediaType(pmtCandidate); - pmtCandidate = NULL; - } /* while */ - IEnumMediaTypes_Release(pEnumCandidates); - } /* if not found */ - } /* if negotiate media type */ - } /* if succeeded */ - LeaveCriticalSection(&This->pin.filter->csFilter); + IEnumMediaTypes_Release(enummt); + }
- TRACE(" -- %x\n", hr); - return hr; + LeaveCriticalSection(&pin->pin.filter->csFilter); + + return VFW_E_NO_ACCEPTABLE_TYPES; }
static HRESULT WINAPI source_ReceiveConnection(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/strmbase/pin.c | 34 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 19 deletions(-)
diff --git a/dlls/strmbase/pin.c b/dlls/strmbase/pin.c index 44831d13f44..58778e57897 100644 --- a/dlls/strmbase/pin.c +++ b/dlls/strmbase/pin.c @@ -431,8 +431,9 @@ static inline struct strmbase_source *impl_source_from_IPin( IPin *iface ) static HRESULT WINAPI source_Connect(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt) { struct strmbase_source *pin = impl_source_from_IPin(iface); - AM_MEDIA_TYPE *candidate; + AM_MEDIA_TYPE candidate, *candidate_ptr; IEnumMediaTypes *enummt; + unsigned int i; ULONG count; HRESULT hr;
@@ -464,37 +465,32 @@ static HRESULT WINAPI source_Connect(IPin *iface, IPin *peer, const AM_MEDIA_TYP return hr; }
- if (SUCCEEDED(IPin_EnumMediaTypes(iface, &enummt))) + for (i = 0; pin->pFuncsTable->base.pin_get_media_type(&pin->pin, i, &candidate) == S_OK; ++i) { - while (IEnumMediaTypes_Next(enummt, 1, &candidate, NULL) == S_OK) + strmbase_dump_media_type(&candidate); + if ((!mt || CompareMediaTypes(mt, &candidate, TRUE)) + && pin->pFuncsTable->pfnAttemptConnection(pin, peer, &candidate) == S_OK) { - if ((!mt || CompareMediaTypes(mt, candidate, TRUE)) - && pin->pFuncsTable->pfnAttemptConnection(pin, peer, candidate) == S_OK) - { - LeaveCriticalSection(&pin->pin.filter->csFilter); - DeleteMediaType(candidate); - IEnumMediaTypes_Release(enummt); - return S_OK; - } - DeleteMediaType(candidate); + LeaveCriticalSection(&pin->pin.filter->csFilter); + FreeMediaType(&candidate); + return S_OK; } - - IEnumMediaTypes_Release(enummt); + FreeMediaType(&candidate); }
if (SUCCEEDED(IPin_EnumMediaTypes(peer, &enummt))) { - while (IEnumMediaTypes_Next(enummt, 1, &candidate, &count) == S_OK) + while (IEnumMediaTypes_Next(enummt, 1, &candidate_ptr, &count) == S_OK) { - if ((!mt || CompareMediaTypes(mt, candidate, TRUE)) - && pin->pFuncsTable->pfnAttemptConnection(pin, peer, candidate) == S_OK) + if ((!mt || CompareMediaTypes(mt, candidate_ptr, TRUE)) + && pin->pFuncsTable->pfnAttemptConnection(pin, peer, candidate_ptr) == S_OK) { LeaveCriticalSection(&pin->pin.filter->csFilter); - DeleteMediaType(candidate); + DeleteMediaType(candidate_ptr); IEnumMediaTypes_Release(enummt); return S_OK; } - DeleteMediaType(candidate); + DeleteMediaType(candidate_ptr); }
IEnumMediaTypes_Release(enummt);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/strmbase/pin.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-)
diff --git a/dlls/strmbase/pin.c b/dlls/strmbase/pin.c index 58778e57897..90064c25d4d 100644 --- a/dlls/strmbase/pin.c +++ b/dlls/strmbase/pin.c @@ -247,12 +247,6 @@ static HRESULT SendFurther(struct strmbase_sink *sink, SendPinFunc func, void *a return hr; }
-static BOOL CompareMediaTypes(const AM_MEDIA_TYPE * pmt1, const AM_MEDIA_TYPE * pmt2, BOOL bWildcards) -{ - return (((bWildcards && (IsEqualGUID(&pmt1->majortype, &GUID_NULL) || IsEqualGUID(&pmt2->majortype, &GUID_NULL))) || IsEqualGUID(&pmt1->majortype, &pmt2->majortype)) && - ((bWildcards && (IsEqualGUID(&pmt1->subtype, &GUID_NULL) || IsEqualGUID(&pmt2->subtype, &GUID_NULL))) || IsEqualGUID(&pmt1->subtype, &pmt2->subtype))); -} - HRESULT strmbase_pin_get_media_type(struct strmbase_pin *iface, unsigned int index, AM_MEDIA_TYPE *mt) { return VFW_S_NO_MORE_ITEMS; @@ -428,6 +422,24 @@ static inline struct strmbase_source *impl_source_from_IPin( IPin *iface ) return CONTAINING_RECORD(iface, struct strmbase_source, pin.IPin_iface); }
+static BOOL compare_media_types(const AM_MEDIA_TYPE *a, const AM_MEDIA_TYPE *b) +{ + if (!a) + return TRUE; + + if (!IsEqualGUID(&a->majortype, &b->majortype) + && !IsEqualGUID(&a->majortype, &GUID_NULL) + && !IsEqualGUID(&b->majortype, &GUID_NULL)) + return FALSE; + + if (!IsEqualGUID(&a->subtype, &b->subtype) + && !IsEqualGUID(&a->subtype, &GUID_NULL) + && !IsEqualGUID(&b->subtype, &GUID_NULL)) + return FALSE; + + return TRUE; +} + static HRESULT WINAPI source_Connect(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt) { struct strmbase_source *pin = impl_source_from_IPin(iface); @@ -468,7 +480,7 @@ static HRESULT WINAPI source_Connect(IPin *iface, IPin *peer, const AM_MEDIA_TYP for (i = 0; pin->pFuncsTable->base.pin_get_media_type(&pin->pin, i, &candidate) == S_OK; ++i) { strmbase_dump_media_type(&candidate); - if ((!mt || CompareMediaTypes(mt, &candidate, TRUE)) + if (compare_media_types(mt, &candidate) && pin->pFuncsTable->pfnAttemptConnection(pin, peer, &candidate) == S_OK) { LeaveCriticalSection(&pin->pin.filter->csFilter); @@ -482,7 +494,7 @@ static HRESULT WINAPI source_Connect(IPin *iface, IPin *peer, const AM_MEDIA_TYP { while (IEnumMediaTypes_Next(enummt, 1, &candidate_ptr, &count) == S_OK) { - if ((!mt || CompareMediaTypes(mt, candidate_ptr, TRUE)) + if (compare_media_types(mt, candidate_ptr) && pin->pFuncsTable->pfnAttemptConnection(pin, peer, candidate_ptr) == S_OK) { LeaveCriticalSection(&pin->pin.filter->csFilter);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/strmbase/pin.c | 7 +++++++ 1 file changed, 7 insertions(+)
diff --git a/dlls/strmbase/pin.c b/dlls/strmbase/pin.c index 90064c25d4d..18631410b77 100644 --- a/dlls/strmbase/pin.c +++ b/dlls/strmbase/pin.c @@ -463,6 +463,13 @@ static HRESULT WINAPI source_Connect(IPin *iface, IPin *peer, const AM_MEDIA_TYP
EnterCriticalSection(&pin->pin.filter->csFilter);
+ if (pin->pin.peer) + { + LeaveCriticalSection(&pin->pin.filter->csFilter); + WARN("Pin is already connected, returning VFW_E_ALREADY_CONNECTED.\n"); + return VFW_E_ALREADY_CONNECTED; + } + if (pin->pin.filter->state != State_Stopped) { LeaveCriticalSection(&pin->pin.filter->csFilter);