quartz: Poll in IMediaFilter::GetState().
Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
23ef268663
commit
df8eabc00a
|
@ -4923,40 +4923,57 @@ static HRESULT WINAPI MediaFilter_GetState(IMediaFilter *iface, DWORD timeout, F
|
||||||
{
|
{
|
||||||
struct filter_graph *graph = impl_from_IMediaFilter(iface);
|
struct filter_graph *graph = impl_from_IMediaFilter(iface);
|
||||||
DWORD end = GetTickCount() + timeout;
|
DWORD end = GetTickCount() + timeout;
|
||||||
HRESULT hr = S_OK, filter_hr;
|
HRESULT hr;
|
||||||
struct filter *filter;
|
|
||||||
|
|
||||||
TRACE("graph %p, timeout %u, state %p.\n", graph, timeout, state);
|
TRACE("graph %p, timeout %u, state %p.\n", graph, timeout, state);
|
||||||
|
|
||||||
if (!state)
|
if (!state)
|
||||||
return E_POINTER;
|
return E_POINTER;
|
||||||
|
|
||||||
EnterCriticalSection(&graph->cs);
|
/* Thread safety is a little tricky here. GetState() shouldn't block other
|
||||||
|
* functions from being called on the filter graph. However, we can't just
|
||||||
|
* call IBaseFilter::GetState() in one loop and drop the lock on every
|
||||||
|
* iteration, since the filter list might change beneath us. So instead we
|
||||||
|
* do what native does, and poll for it every 10 ms. */
|
||||||
|
|
||||||
|
EnterCriticalSection(&graph->cs);
|
||||||
*state = graph->state;
|
*state = graph->state;
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY(filter, &graph->filters, struct filter, entry)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
IBaseFilter *async_filter = NULL;
|
||||||
FILTER_STATE filter_state;
|
FILTER_STATE filter_state;
|
||||||
int wait;
|
struct filter *filter;
|
||||||
|
|
||||||
if (timeout == INFINITE)
|
hr = S_OK;
|
||||||
wait = INFINITE;
|
|
||||||
else if (!timeout)
|
|
||||||
wait = 0;
|
|
||||||
else
|
|
||||||
wait = max(end - GetTickCount(), 0);
|
|
||||||
|
|
||||||
filter_hr = IBaseFilter_GetState(filter->filter, wait, &filter_state);
|
LIST_FOR_EACH_ENTRY(filter, &graph->filters, struct filter, entry)
|
||||||
if (hr == S_OK && filter_hr == VFW_S_STATE_INTERMEDIATE)
|
{
|
||||||
hr = VFW_S_STATE_INTERMEDIATE;
|
HRESULT filter_hr = IBaseFilter_GetState(filter->filter, 0, &filter_state);
|
||||||
else if (filter_hr != S_OK && filter_hr != VFW_S_STATE_INTERMEDIATE)
|
|
||||||
hr = filter_hr;
|
TRACE("Filter %p returned hr %#x, state %u.\n", filter->filter, filter_hr, filter_state);
|
||||||
if (filter_state != graph->state)
|
|
||||||
ERR("Filter %p reported incorrect state %u.\n", filter->filter, filter_state);
|
if (filter_hr == VFW_S_STATE_INTERMEDIATE)
|
||||||
|
async_filter = filter->filter;
|
||||||
|
|
||||||
|
if (hr == S_OK && filter_hr == VFW_S_STATE_INTERMEDIATE)
|
||||||
|
hr = VFW_S_STATE_INTERMEDIATE;
|
||||||
|
else if (filter_hr != S_OK && filter_hr != VFW_S_STATE_INTERMEDIATE)
|
||||||
|
hr = filter_hr;
|
||||||
|
if (filter_state != graph->state)
|
||||||
|
ERR("Filter %p reported incorrect state %u.\n", filter->filter, filter_state);
|
||||||
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection(&graph->cs);
|
||||||
|
|
||||||
|
if (hr != VFW_S_STATE_INTERMEDIATE || (timeout != INFINITE && GetTickCount() >= end))
|
||||||
|
break;
|
||||||
|
|
||||||
|
IBaseFilter_GetState(async_filter, 10, &filter_state);
|
||||||
|
|
||||||
|
EnterCriticalSection(&graph->cs);
|
||||||
}
|
}
|
||||||
|
|
||||||
LeaveCriticalSection(&graph->cs);
|
|
||||||
TRACE("Returning %#x, state %u.\n", hr, *state);
|
TRACE("Returning %#x, state %u.\n", hr, *state);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue