[PATCH] strmbase: Attempt connection using source pin's current media type.
Jeff Smith
whydoubt at gmail.com
Wed Aug 26 22:29:43 CDT 2020
Signed-off-by: Jeff Smith <whydoubt at gmail.com>
---
If no media type is specified, IPin::Connect() currently attempts to
connect pins using any accepted media type. With this patch, it first
attempts to connect using the source pin's current media type.
dlls/qcap/tests/videocapture.c | 64 ++++++++++++++++++++++++++++++++--
dlls/strmbase/pin.c | 27 ++++++++++++++
2 files changed, 88 insertions(+), 3 deletions(-)
diff --git a/dlls/qcap/tests/videocapture.c b/dlls/qcap/tests/videocapture.c
index 80d4899410..7938b48376 100644
--- a/dlls/qcap/tests/videocapture.c
+++ b/dlls/qcap/tests/videocapture.c
@@ -174,7 +174,51 @@ static void test_stream_config(IPin *pin)
IAMStreamConfig_Release(stream_config);
}
-static void test_capture(IBaseFilter *filter)
+static void test_connect(IPin *source_pin, IPin *sink_pin)
+{
+ IEnumMediaTypes *enum_media_types;
+ IAMStreamConfig *stream_config;
+ AM_MEDIA_TYPE mt, *pmt;
+ HRESULT hr;
+
+ hr = IPin_QueryInterface(source_pin, &IID_IAMStreamConfig, (void **)&stream_config);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ hr = IPin_EnumMediaTypes(source_pin, &enum_media_types);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ while (IEnumMediaTypes_Next(enum_media_types, 1, &pmt, NULL) == S_OK)
+ {
+ hr = IAMStreamConfig_SetFormat(stream_config, pmt);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ hr = IPin_Connect(source_pin, sink_pin, NULL);
+ if (hr == S_OK)
+ {
+ hr = IPin_ConnectionMediaType(source_pin, &mt);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ ok(IsEqualGUID(&pmt->majortype, &mt.majortype), "majortype did not match.\n");
+ ok(IsEqualGUID(&pmt->subtype, &mt.subtype), "subtype did not match.\n");
+ ok(IsEqualGUID(&pmt->formattype, &mt.formattype), "formattype did not match.\n");
+ ok(memcmp(pmt->pbFormat, mt.pbFormat, mt.cbFormat) == 0, "format details did not match.\n");
+
+ FreeMediaType(&mt);
+
+ hr = IPin_Disconnect(source_pin);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ hr = IPin_Disconnect(sink_pin);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+ }
+
+ CoTaskMemFree(pmt);
+ }
+
+ IEnumMediaTypes_Release(enum_media_types);
+ IAMStreamConfig_Release(stream_config);
+}
+
+static void test_capture(IBaseFilter *filter, IPin *sink_pin)
{
IEnumPins *enum_pins;
IPin *pin;
@@ -209,6 +253,10 @@ static void test_capture(IBaseFilter *filter)
check_interface(pin, &IID_IAMVideoCompression, FALSE);
check_interface(pin, &IID_IAMVideoProcAmp, FALSE);
check_interface(pin, &IID_IPersistPropertyBag, FALSE);
+
+ /* Placed after check_inferface tests, as it can affect the
+ * result for IID_IAMDroppedFrames on Windows. */
+ test_connect(pin, sink_pin);
}
IPin_Release(pin);
}
@@ -255,7 +303,8 @@ START_TEST(videocapture)
{
ICreateDevEnum *dev_enum;
IEnumMoniker *class_enum;
- IBaseFilter *filter;
+ IBaseFilter *filter, *null_renderer;
+ IPin *null_renderer_pin;
IMoniker *moniker;
WCHAR *name;
HRESULT hr;
@@ -277,6 +326,13 @@ START_TEST(videocapture)
}
ok(hr == S_OK, "Got hr=%#x.\n", hr);
+ hr = CoCreateInstance(&CLSID_NullRenderer, NULL, CLSCTX_INPROC,
+ &IID_IBaseFilter, (void **)&null_renderer);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+ hr = IBaseFilter_FindPin(null_renderer, L"In", &null_renderer_pin);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
+
while (IEnumMoniker_Next(class_enum, 1, &moniker, NULL) == S_OK)
{
hr = IMoniker_GetDisplayName(moniker, NULL, NULL, &name);
@@ -287,7 +343,7 @@ START_TEST(videocapture)
hr = IMoniker_BindToObject(moniker, NULL, NULL, &IID_IBaseFilter, (void**)&filter);
if (hr == S_OK)
{
- test_capture(filter);
+ test_capture(filter, null_renderer_pin);
test_misc_flags(filter);
ref = IBaseFilter_Release(filter);
ok(!ref, "Got outstanding refcount %d.\n", ref);
@@ -298,6 +354,8 @@ START_TEST(videocapture)
IMoniker_Release(moniker);
}
+ IPin_Release(null_renderer_pin);
+ IBaseFilter_Release(null_renderer);
ICreateDevEnum_Release(dev_enum);
IEnumMoniker_Release(class_enum);
CoUninitialize();
diff --git a/dlls/strmbase/pin.c b/dlls/strmbase/pin.c
index e5017c2ff9..35aa6bc77d 100644
--- a/dlls/strmbase/pin.c
+++ b/dlls/strmbase/pin.c
@@ -510,6 +510,33 @@ static HRESULT WINAPI source_Connect(IPin *iface, IPin *peer, const AM_MEDIA_TYP
return VFW_E_NOT_STOPPED;
}
+ if (!mt)
+ {
+ IAMStreamConfig *stream_config = NULL;
+
+ if (pin->pFuncsTable->base.pin_query_interface)
+ pin->pFuncsTable->base.pin_query_interface(&pin->pin, &IID_IAMStreamConfig,
+ (void **)&stream_config);
+
+ if (stream_config)
+ {
+ AM_MEDIA_TYPE *pmt = NULL;
+ IAMStreamConfig_GetFormat(stream_config, &pmt);
+ if (pmt)
+ {
+ if (pin->pFuncsTable->pfnAttemptConnection(pin, peer, pmt) == S_OK)
+ {
+ LeaveCriticalSection(&pin->pin.filter->csFilter);
+ DeleteMediaType(pmt);
+ IAMStreamConfig_Release(stream_config);
+ return S_OK;
+ }
+ DeleteMediaType(pmt);
+ }
+ IAMStreamConfig_Release(stream_config);
+ }
+ }
+
/* We don't check the subtype here. The rationale (as given by the DirectX
* documentation) is that the format type is supposed to provide at least
* as much information as the subtype. */
--
2.23.0
More information about the wine-devel
mailing list