quartz/filesource: Share pin and filter reference counts.

Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Zebediah Figura 2019-06-16 19:35:00 -05:00 committed by Alexandre Julliard
parent 3c40ce0549
commit 5f08add0b3
2 changed files with 55 additions and 63 deletions

View File

@ -50,6 +50,37 @@ static const AM_MEDIA_TYPE default_mt =
NULL 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 typedef struct AsyncReader
{ {
BaseFilter filter; BaseFilter filter;
@ -407,14 +438,28 @@ static void async_reader_destroy(BaseFilter *iface)
if (filter->pOutputPin) if (filter->pOutputPin)
{ {
FileAsyncReader *pin = impl_from_IPin(filter->pOutputPin);
unsigned int i;
IPin *peer; IPin *peer;
if (SUCCEEDED(IPin_ConnectedTo(filter->pOutputPin, &peer))) if (SUCCEEDED(IPin_ConnectedTo(filter->pOutputPin, &peer)))
{ {
IPin_Disconnect(peer); IPin_Disconnect(peer);
IPin_Release(peer); IPin_Release(peer);
} }
IPin_Disconnect(filter->pOutputPin); 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); CoTaskMemFree(filter->pszFileName);
if (filter->pmt) if (filter->pmt)
@ -658,39 +703,6 @@ static const IFileSourceFilterVtbl FileSource_Vtbl =
FileSource_GetCurFile 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) static inline FileAsyncReader *impl_from_BasePin(BasePin *iface)
{ {
return CONTAINING_RECORD(iface, FileAsyncReader, pin.pin); return CONTAINING_RECORD(iface, FileAsyncReader, pin.pin);
@ -765,36 +777,22 @@ static HRESULT WINAPI FileAsyncReaderPin_QueryInterface(IPin * iface, REFIID rii
return E_NOINTERFACE; return E_NOINTERFACE;
} }
static ULONG WINAPI FileAsyncReaderPin_AddRef(IPin *iface)
{
FileAsyncReader *pin = impl_from_IPin(iface);
return IBaseFilter_AddRef(pin->pin.pin.pinInfo.pFilter);
}
static ULONG WINAPI FileAsyncReaderPin_Release(IPin * iface) static ULONG WINAPI FileAsyncReaderPin_Release(IPin * iface)
{ {
FileAsyncReader *This = impl_from_IPin(iface); FileAsyncReader *pin = impl_from_IPin(iface);
ULONG refCount = InterlockedDecrement(&This->pin.pin.refCount); return IBaseFilter_Release(pin->pin.pin.pinInfo.pFilter);
int x;
TRACE("(%p)->() Release from %d\n", This, refCount + 1);
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 const IPinVtbl FileAsyncReaderPin_Vtbl = static const IPinVtbl FileAsyncReaderPin_Vtbl =
{ {
FileAsyncReaderPin_QueryInterface, FileAsyncReaderPin_QueryInterface,
BasePinImpl_AddRef, FileAsyncReaderPin_AddRef,
FileAsyncReaderPin_Release, FileAsyncReaderPin_Release,
BaseOutputPinImpl_Connect, BaseOutputPinImpl_Connect,
BaseOutputPinImpl_ReceiveConnection, BaseOutputPinImpl_ReceiveConnection,

View File

@ -539,10 +539,8 @@ todo_wine
hr = IEnumPins_Next(enum1, 1, pins, NULL); hr = IEnumPins_Next(enum1, 1, pins, NULL);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
ref = get_refcount(filter); ref = get_refcount(filter);
todo_wine
ok(ref == 3, "Got unexpected refcount %d.\n", ref); ok(ref == 3, "Got unexpected refcount %d.\n", ref);
ref = get_refcount(pins[0]); ref = get_refcount(pins[0]);
todo_wine
ok(ref == 3, "Got unexpected refcount %d.\n", ref); ok(ref == 3, "Got unexpected refcount %d.\n", ref);
ref = get_refcount(enum1); ref = get_refcount(enum1);
ok(ref == 1, "Got unexpected refcount %d.\n", ref); 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); hr = IBaseFilter_FindPin(filter, source_id, &pin);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
ref = get_refcount(filter); ref = get_refcount(filter);
todo_wine
ok(ref == 2, "Got unexpected refcount %d.\n", ref); ok(ref == 2, "Got unexpected refcount %d.\n", ref);
ref = get_refcount(pin); ref = get_refcount(pin);
ok(ref == 2, "Got unexpected refcount %d.\n", ref); 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); hr = IBaseFilter_FindPin(filter, source_id, &pin);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
ref = get_refcount(filter); ref = get_refcount(filter);
todo_wine
ok(ref == 2, "Got unexpected refcount %d.\n", ref); ok(ref == 2, "Got unexpected refcount %d.\n", ref);
ref = get_refcount(pin); ref = get_refcount(pin);
ok(ref == 2, "Got unexpected refcount %d.\n", ref); 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(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)); ok(!lstrcmpW(info.achName, source_id), "Got name %s.\n", wine_dbgstr_w(info.achName));
ref = get_refcount(filter); ref = get_refcount(filter);
todo_wine
ok(ref == 3, "Got unexpected refcount %d.\n", ref); ok(ref == 3, "Got unexpected refcount %d.\n", ref);
ref = get_refcount(pin); ref = get_refcount(pin);
todo_wine
ok(ref == 3, "Got unexpected refcount %d.\n", ref); ok(ref == 3, "Got unexpected refcount %d.\n", ref);
IBaseFilter_Release(info.pFilter); IBaseFilter_Release(info.pFilter);