quartz: Optimize the file source to do its job better.
This commit is contained in:
parent
7934951343
commit
12a0fd3d8b
|
@ -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;
|
||||||
|
|
||||||
for (x = 0; x < This->samples; ++x)
|
/* Try to insert above the waiting sample if possible */
|
||||||
|
for (x = wait + 1; x < This->samples; ++x)
|
||||||
{
|
{
|
||||||
if (!This->sample_list[x].pSample)
|
if (!This->sample_list[x].pSample)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (x >= This->samples)
|
||||||
|
for (x = 0; x < This->samples; ++x)
|
||||||
|
{
|
||||||
|
if (!This->sample_list[x].pSample)
|
||||||
|
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,7 +1180,10 @@ 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)
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue