Zebediah Figura : quartz/filesource: Share pin and filter reference counts.

Alexandre Julliard julliard at winehq.org
Mon Jun 17 15:54:19 CDT 2019


Module: wine
Branch: master
Commit: 5f08add0b32eb4d2386ce170f2dd3f3c98ff0ac0
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=5f08add0b32eb4d2386ce170f2dd3f3c98ff0ac0

Author: Zebediah Figura <z.figura12 at gmail.com>
Date:   Sun Jun 16 19:35:00 2019 -0500

quartz/filesource: Share pin and filter reference counts.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/quartz/filesource.c       | 112 ++++++++++++++++++++---------------------
 dlls/quartz/tests/filesource.c |   6 ---
 2 files changed, 55 insertions(+), 63 deletions(-)

diff --git a/dlls/quartz/filesource.c b/dlls/quartz/filesource.c
index 34601da..25bffe6 100644
--- a/dlls/quartz/filesource.c
+++ b/dlls/quartz/filesource.c
@@ -50,6 +50,37 @@ static const AM_MEDIA_TYPE default_mt =
     NULL
 };
 
+typedef struct DATAREQUEST
+{
+    IMediaSample *pSample;
+    DWORD_PTR dwUserData;
+    OVERLAPPED ovl;
+} DATAREQUEST;
+
+typedef struct FileAsyncReader
+{
+    BaseOutputPin pin;
+    IAsyncReader IAsyncReader_iface;
+
+    ALLOCATOR_PROPERTIES allocProps;
+    HANDLE hFile;
+    BOOL bFlushing;
+    /* Why would you need more? Every sample has its own handle */
+    LONG queued_number;
+    LONG samples;
+    LONG oldest_sample;
+    CRITICAL_SECTION csList;
+    DATAREQUEST *sample_list;
+
+    /* Have a handle for every sample, and then one more as flushing handle */
+    HANDLE *handle_list;
+} FileAsyncReader;
+
+static inline FileAsyncReader *impl_from_IPin(IPin *iface)
+{
+    return CONTAINING_RECORD(iface, FileAsyncReader, pin.pin.IPin_iface);
+}
+
 typedef struct AsyncReader
 {
     BaseFilter filter;
@@ -407,14 +438,28 @@ static void async_reader_destroy(BaseFilter *iface)
 
     if (filter->pOutputPin)
     {
+        FileAsyncReader *pin = impl_from_IPin(filter->pOutputPin);
+        unsigned int i;
         IPin *peer;
+
         if (SUCCEEDED(IPin_ConnectedTo(filter->pOutputPin, &peer)))
         {
             IPin_Disconnect(peer);
             IPin_Release(peer);
         }
         IPin_Disconnect(filter->pOutputPin);
-        IPin_Release(filter->pOutputPin);
+
+        CoTaskMemFree(pin->sample_list);
+        if (pin->handle_list)
+        {
+            for (i = 0; i <= pin->samples; ++i)
+                CloseHandle(pin->handle_list[i]);
+            CoTaskMemFree(pin->handle_list);
+        }
+        CloseHandle(pin->hFile);
+        pin->csList.DebugInfo->Spare[0] = 0;
+        DeleteCriticalSection(&pin->csList);
+        BaseOutputPin_Destroy(&pin->pin);
     }
     CoTaskMemFree(filter->pszFileName);
     if (filter->pmt)
@@ -658,39 +703,6 @@ static const IFileSourceFilterVtbl FileSource_Vtbl =
     FileSource_GetCurFile
 };
 
-
-/* the dwUserData passed back to user */
-typedef struct DATAREQUEST
-{
-    IMediaSample * pSample; /* sample passed to us by user */
-    DWORD_PTR dwUserData; /* user data passed to us */
-    OVERLAPPED ovl; /* our overlapped structure */
-} DATAREQUEST;
-
-typedef struct FileAsyncReader
-{
-    BaseOutputPin pin;
-    IAsyncReader IAsyncReader_iface;
-
-    ALLOCATOR_PROPERTIES allocProps;
-    HANDLE hFile;
-    BOOL bFlushing;
-    /* Why would you need more? Every sample has its own handle */
-    LONG queued_number;
-    LONG samples;
-    LONG oldest_sample;
-    CRITICAL_SECTION csList; /* critical section to prevent concurrency issues */
-    DATAREQUEST *sample_list;
-
-    /* Have a handle for every sample, and then one more as flushing handle */
-    HANDLE *handle_list;
-} FileAsyncReader;
-
-static inline FileAsyncReader *impl_from_IPin(IPin *iface)
-{
-    return CONTAINING_RECORD(iface, FileAsyncReader, pin.pin.IPin_iface);
-}
-
 static inline FileAsyncReader *impl_from_BasePin(BasePin *iface)
 {
     return CONTAINING_RECORD(iface, FileAsyncReader, pin.pin);
@@ -765,36 +777,22 @@ static HRESULT WINAPI FileAsyncReaderPin_QueryInterface(IPin * iface, REFIID rii
     return E_NOINTERFACE;
 }
 
-static ULONG WINAPI FileAsyncReaderPin_Release(IPin * iface)
+static ULONG WINAPI FileAsyncReaderPin_AddRef(IPin *iface)
 {
-    FileAsyncReader *This = impl_from_IPin(iface);
-    ULONG refCount = InterlockedDecrement(&This->pin.pin.refCount);
-    int x;
-
-    TRACE("(%p)->() Release from %d\n", This, refCount + 1);
+    FileAsyncReader *pin = impl_from_IPin(iface);
+    return IBaseFilter_AddRef(pin->pin.pin.pinInfo.pFilter);
+}
 
-    if (!refCount)
-    {
-        CoTaskMemFree(This->sample_list);
-        if (This->handle_list)
-        {
-            for (x = 0; x <= This->samples; ++x)
-                CloseHandle(This->handle_list[x]);
-            CoTaskMemFree(This->handle_list);
-        }
-        CloseHandle(This->hFile);
-        This->csList.DebugInfo->Spare[0] = 0;
-        DeleteCriticalSection(&This->csList);
-        BaseOutputPin_Destroy(&This->pin);
-        return 0;
-    }
-    return refCount;
+static ULONG WINAPI FileAsyncReaderPin_Release(IPin * iface)
+{
+    FileAsyncReader *pin = impl_from_IPin(iface);
+    return IBaseFilter_Release(pin->pin.pin.pinInfo.pFilter);
 }
 
 static const IPinVtbl FileAsyncReaderPin_Vtbl = 
 {
     FileAsyncReaderPin_QueryInterface,
-    BasePinImpl_AddRef,
+    FileAsyncReaderPin_AddRef,
     FileAsyncReaderPin_Release,
     BaseOutputPinImpl_Connect,
     BaseOutputPinImpl_ReceiveConnection,
diff --git a/dlls/quartz/tests/filesource.c b/dlls/quartz/tests/filesource.c
index 0bac51d..b1a8399 100644
--- a/dlls/quartz/tests/filesource.c
+++ b/dlls/quartz/tests/filesource.c
@@ -539,10 +539,8 @@ todo_wine
     hr = IEnumPins_Next(enum1, 1, pins, NULL);
     ok(hr == S_OK, "Got hr %#x.\n", hr);
     ref = get_refcount(filter);
-todo_wine
     ok(ref == 3, "Got unexpected refcount %d.\n", ref);
     ref = get_refcount(pins[0]);
-todo_wine
     ok(ref == 3, "Got unexpected refcount %d.\n", ref);
     ref = get_refcount(enum1);
     ok(ref == 1, "Got unexpected refcount %d.\n", ref);
@@ -624,7 +622,6 @@ static void test_find_pin(void)
     hr = IBaseFilter_FindPin(filter, source_id, &pin);
     ok(hr == S_OK, "Got hr %#x.\n", hr);
     ref = get_refcount(filter);
-todo_wine
     ok(ref == 2, "Got unexpected refcount %d.\n", ref);
     ref = get_refcount(pin);
     ok(ref == 2, "Got unexpected refcount %d.\n", ref);
@@ -662,7 +659,6 @@ static void test_pin_info(void)
     hr = IBaseFilter_FindPin(filter, source_id, &pin);
     ok(hr == S_OK, "Got hr %#x.\n", hr);
     ref = get_refcount(filter);
-todo_wine
     ok(ref == 2, "Got unexpected refcount %d.\n", ref);
     ref = get_refcount(pin);
     ok(ref == 2, "Got unexpected refcount %d.\n", ref);
@@ -673,10 +669,8 @@ todo_wine
     ok(info.dir == PINDIR_OUTPUT, "Got direction %d.\n", info.dir);
     ok(!lstrcmpW(info.achName, source_id), "Got name %s.\n", wine_dbgstr_w(info.achName));
     ref = get_refcount(filter);
-todo_wine
     ok(ref == 3, "Got unexpected refcount %d.\n", ref);
     ref = get_refcount(pin);
-todo_wine
     ok(ref == 3, "Got unexpected refcount %d.\n", ref);
     IBaseFilter_Release(info.pFilter);
 




More information about the wine-cvs mailing list