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