quartz: Optimize the file source to do its job better.

This commit is contained in:
Maarten Lankhorst 2008-04-25 14:33:15 -07:00 committed by Alexandre Julliard
parent 7934951343
commit 12a0fd3d8b
1 changed files with 33 additions and 9 deletions

View File

@ -769,6 +769,8 @@ typedef struct FileAsyncReader
LONG samples; LONG samples;
CRITICAL_SECTION csList; /* critical section to prevent concurrency issues */ CRITICAL_SECTION csList; /* critical section to prevent concurrency issues */
DATAREQUEST *sample_list; DATAREQUEST *sample_list;
/* Have a handle for every sample, and then one more as flushing handle */
HANDLE *handle_list; HANDLE *handle_list;
} FileAsyncReader; } FileAsyncReader;
@ -832,7 +834,7 @@ static ULONG WINAPI FileAsyncReaderPin_Release(IPin * iface)
CoTaskMemFree(This->sample_list); CoTaskMemFree(This->sample_list);
if (This->handle_list) if (This->handle_list)
{ {
for (x = 0; x < This->samples; ++x) for (x = 0; x <= This->samples; ++x)
CloseHandle(This->handle_list[x]); CloseHandle(This->handle_list[x]);
CoTaskMemFree(This->handle_list); CoTaskMemFree(This->handle_list);
} }
@ -1009,7 +1011,7 @@ done:
if (This->handle_list) if (This->handle_list)
{ {
int x; int x;
for (x = 0; x < This->samples; ++x) for (x = 0; x <= This->samples; ++x)
CloseHandle(This->handle_list[x]); CloseHandle(This->handle_list[x]);
CoTaskMemFree(This->handle_list); CoTaskMemFree(This->handle_list);
} }
@ -1017,7 +1019,7 @@ done:
This->samples = pProps->cBuffers; This->samples = pProps->cBuffers;
TRACE("Samples: %u\n", This->samples); TRACE("Samples: %u\n", This->samples);
This->sample_list = CoTaskMemAlloc(sizeof(This->sample_list[0]) * pProps->cBuffers); This->sample_list = CoTaskMemAlloc(sizeof(This->sample_list[0]) * pProps->cBuffers);
This->handle_list = CoTaskMemAlloc(sizeof(HANDLE) * pProps->cBuffers); This->handle_list = CoTaskMemAlloc(sizeof(HANDLE) * (pProps->cBuffers + 1));
if (This->sample_list && This->handle_list) if (This->sample_list && This->handle_list)
{ {
@ -1027,6 +1029,7 @@ done:
{ {
This->sample_list[x].ovl.hEvent = This->handle_list[x] = CreateEventW(NULL, 0, 0, NULL); This->sample_list[x].ovl.hEvent = This->handle_list[x] = CreateEventW(NULL, 0, 0, NULL);
} }
This->handle_list[This->samples] = CreateEventW(NULL, 1, 0, NULL);
This->pin.allocProps = *pProps; This->pin.allocProps = *pProps;
} }
else else
@ -1060,6 +1063,7 @@ static HRESULT WINAPI FileAsyncReader_Request(IAsyncReader * iface, IMediaSample
REFERENCE_TIME Stop; REFERENCE_TIME Stop;
FileAsyncReader *This = impl_from_IAsyncReader(iface); FileAsyncReader *This = impl_from_IAsyncReader(iface);
LPBYTE pBuffer = NULL; LPBYTE pBuffer = NULL;
DWORD wait;
TRACE("(%p, %lx)\n", pSample, dwUser); TRACE("(%p, %lx)\n", pSample, dwUser);
@ -1080,17 +1084,32 @@ static HRESULT WINAPI FileAsyncReader_Request(IAsyncReader * iface, IMediaSample
return VFW_E_WRONG_STATE; return VFW_E_WRONG_STATE;
} }
wait = WaitForMultipleObjectsEx(This->samples, This->handle_list, FALSE, 0, FALSE);
if (wait < This->samples - 1)
SetEvent(This->handle_list[wait]);
else
wait = This->samples;
if (SUCCEEDED(hr)) if (SUCCEEDED(hr))
{ {
DWORD dwLength = (DWORD) BYTES_FROM_MEDIATIME(Stop - Start); DWORD dwLength = (DWORD) BYTES_FROM_MEDIATIME(Stop - Start);
DATAREQUEST *pDataRq; DATAREQUEST *pDataRq;
int x; int x;
/* Try to insert above the waiting sample if possible */
for (x = wait + 1; x < This->samples; ++x)
{
if (!This->sample_list[x].pSample)
break;
}
if (x >= This->samples)
for (x = 0; x < This->samples; ++x) for (x = 0; x < This->samples; ++x)
{ {
if (!This->sample_list[x].pSample) if (!This->sample_list[x].pSample)
break; break;
} }
assert(x < This->samples); assert(x < This->samples);
InterlockedIncrement(&This->queued_number); InterlockedIncrement(&This->queued_number);
@ -1138,20 +1157,20 @@ static HRESULT WINAPI FileAsyncReader_WaitForNext(IAsyncReader * iface, DWORD dw
{ {
if (!This->queued_number) if (!This->queued_number)
{ {
ERR("Called without samples in queue and not flushing!!\n"); /* It could be that nothing is queued right now, but that can be fixed */
return E_FAIL; WARN("Called without samples in queue and not flushing!!\n");
} }
/* wait for an object to read, or time out */ /* wait for an object to read, or time out */
buffer = WaitForMultipleObjectsEx(This->samples, This->handle_list, FALSE, dwTimeout, TRUE); buffer = WaitForMultipleObjectsEx(This->samples+1, This->handle_list, FALSE, dwTimeout, TRUE);
if (buffer >= MAXIMUM_WAIT_OBJECTS) if (buffer >= This->samples)
{ {
FIXME("Returned: %u (%08x)\n", buffer, GetLastError()); FIXME("Returned: %u (%08x)\n", buffer, GetLastError());
hr = VFW_E_TIMEOUT; hr = VFW_E_TIMEOUT;
buffer = ~0; buffer = ~0;
} }
else else if (buffer < This->samples)
InterlockedDecrement(&This->queued_number); InterlockedDecrement(&This->queued_number);
} }
@ -1161,8 +1180,11 @@ static HRESULT WINAPI FileAsyncReader_WaitForNext(IAsyncReader * iface, DWORD dw
for (buffer = 0; buffer < This->samples; ++buffer) for (buffer = 0; buffer < This->samples; ++buffer)
{ {
if (This->sample_list[buffer].pSample) if (This->sample_list[buffer].pSample)
{
ResetEvent(This->handle_list[buffer]);
break; break;
} }
}
if (buffer == This->samples) if (buffer == This->samples)
{ {
assert(!This->queued_number); assert(!This->queued_number);
@ -1311,6 +1333,7 @@ static HRESULT WINAPI FileAsyncReader_BeginFlush(IAsyncReader * iface)
EnterCriticalSection(&This->csList); EnterCriticalSection(&This->csList);
This->bFlushing = TRUE; This->bFlushing = TRUE;
CancelIo(This->hFile); CancelIo(This->hFile);
SetEvent(This->handle_list[This->samples]);
LeaveCriticalSection(&This->csList); LeaveCriticalSection(&This->csList);
return S_OK; return S_OK;
@ -1323,6 +1346,7 @@ static HRESULT WINAPI FileAsyncReader_EndFlush(IAsyncReader * iface)
TRACE("()\n"); TRACE("()\n");
EnterCriticalSection(&This->csList); EnterCriticalSection(&This->csList);
ResetEvent(This->handle_list[This->samples]);
This->bFlushing = FALSE; This->bFlushing = FALSE;
LeaveCriticalSection(&This->csList); LeaveCriticalSection(&This->csList);