Signed-off-by: Zebediah Figura z.figura12@gmail.com --- 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 34601da6b47..25bffe6c36c 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 0bac51d799d..b1a8399d6e9 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);