[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