quartz: Implement MediaControl_GetState.
This allows applications to wait for state transitions to be really complete. Fixes some xvid crashes.
This commit is contained in:
parent
aaee8a1b0e
commit
29b6dbab80
|
@ -1555,9 +1555,9 @@ static HRESULT WINAPI MediaControl_Invoke(IMediaControl *iface,
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef HRESULT(WINAPI *fnFoundFilter)(IBaseFilter *);
|
typedef HRESULT(WINAPI *fnFoundFilter)(IBaseFilter *, DWORD_PTR data);
|
||||||
|
|
||||||
static HRESULT ExploreGraph(IFilterGraphImpl* pGraph, IPin* pOutputPin, fnFoundFilter FoundFilter)
|
static HRESULT ExploreGraph(IFilterGraphImpl* pGraph, IPin* pOutputPin, fnFoundFilter FoundFilter, DWORD_PTR data)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
IPin* pInputPin;
|
IPin* pInputPin;
|
||||||
|
@ -1594,7 +1594,7 @@ static HRESULT ExploreGraph(IFilterGraphImpl* pGraph, IPin* pOutputPin, fnFoundF
|
||||||
/* Explore the graph downstream from this pin
|
/* Explore the graph downstream from this pin
|
||||||
* FIXME: We should prevent exploring from a pin more than once. This can happens when
|
* FIXME: We should prevent exploring from a pin more than once. This can happens when
|
||||||
* several input pins are connected to the same output (a MUX for instance). */
|
* several input pins are connected to the same output (a MUX for instance). */
|
||||||
ExploreGraph(pGraph, ppPins[i], FoundFilter);
|
ExploreGraph(pGraph, ppPins[i], FoundFilter, data);
|
||||||
IPin_Release(ppPins[i]);
|
IPin_Release(ppPins[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1602,14 +1602,15 @@ static HRESULT ExploreGraph(IFilterGraphImpl* pGraph, IPin* pOutputPin, fnFoundF
|
||||||
}
|
}
|
||||||
TRACE("Doing stuff with filter %p\n", PinInfo.pFilter);
|
TRACE("Doing stuff with filter %p\n", PinInfo.pFilter);
|
||||||
|
|
||||||
FoundFilter(PinInfo.pFilter);
|
FoundFilter(PinInfo.pFilter, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (PinInfo.pFilter) IBaseFilter_Release(PinInfo.pFilter);
|
if (PinInfo.pFilter) IBaseFilter_Release(PinInfo.pFilter);
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI SendRun(IBaseFilter *pFilter) {
|
static HRESULT WINAPI SendRun(IBaseFilter *pFilter, DWORD_PTR data)
|
||||||
|
{
|
||||||
LONGLONG time = 0;
|
LONGLONG time = 0;
|
||||||
IReferenceClock *clock = NULL;
|
IReferenceClock *clock = NULL;
|
||||||
|
|
||||||
|
@ -1628,15 +1629,39 @@ static HRESULT WINAPI SendRun(IBaseFilter *pFilter) {
|
||||||
return IBaseFilter_Run(pFilter, time);
|
return IBaseFilter_Run(pFilter, time);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI SendPause(IBaseFilter *pFilter) {
|
static HRESULT WINAPI SendPause(IBaseFilter *pFilter, DWORD_PTR data)
|
||||||
|
{
|
||||||
return IBaseFilter_Pause(pFilter);
|
return IBaseFilter_Pause(pFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT WINAPI SendStop(IBaseFilter *pFilter) {
|
static HRESULT WINAPI SendStop(IBaseFilter *pFilter, DWORD_PTR data)
|
||||||
|
{
|
||||||
return IBaseFilter_Stop(pFilter);
|
return IBaseFilter_Stop(pFilter);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT SendFilterMessage(IMediaControl *iface, fnFoundFilter FoundFilter) {
|
static HRESULT WINAPI SendGetState(IBaseFilter *pFilter, DWORD_PTR data)
|
||||||
|
{
|
||||||
|
FILTER_STATE state;
|
||||||
|
DWORD time_end = data;
|
||||||
|
DWORD time_now = GetTickCount();
|
||||||
|
LONG wait;
|
||||||
|
|
||||||
|
if (time_end == INFINITE)
|
||||||
|
{
|
||||||
|
wait = INFINITE;
|
||||||
|
}
|
||||||
|
else if (time_end > time_now)
|
||||||
|
{
|
||||||
|
wait = time_end - time_now;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
wait = 0;
|
||||||
|
|
||||||
|
return IBaseFilter_GetState(pFilter, wait, &state);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static HRESULT SendFilterMessage(IMediaControl *iface, fnFoundFilter FoundFilter, DWORD_PTR data) {
|
||||||
ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
|
ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
|
||||||
int i;
|
int i;
|
||||||
IBaseFilter* pfilter;
|
IBaseFilter* pfilter;
|
||||||
|
@ -1680,10 +1705,10 @@ static HRESULT SendFilterMessage(IMediaControl *iface, fnFoundFilter FoundFilter
|
||||||
while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK)
|
while(IEnumPins_Next(pEnum, 1, &pPin, &dummy) == S_OK)
|
||||||
{
|
{
|
||||||
/* Explore the graph downstream from this pin */
|
/* Explore the graph downstream from this pin */
|
||||||
ExploreGraph(This, pPin, FoundFilter);
|
ExploreGraph(This, pPin, FoundFilter, data);
|
||||||
IPin_Release(pPin);
|
IPin_Release(pPin);
|
||||||
}
|
}
|
||||||
FoundFilter(pfilter);
|
FoundFilter(pfilter, data);
|
||||||
}
|
}
|
||||||
IEnumPins_Release(pEnum);
|
IEnumPins_Release(pEnum);
|
||||||
}
|
}
|
||||||
|
@ -1709,7 +1734,7 @@ static HRESULT WINAPI MediaControl_Run(IMediaControl *iface) {
|
||||||
}
|
}
|
||||||
else This->position = This->start_time = 0;
|
else This->position = This->start_time = 0;
|
||||||
|
|
||||||
SendFilterMessage(iface, SendRun);
|
SendFilterMessage(iface, SendRun, 0);
|
||||||
This->state = State_Running;
|
This->state = State_Running;
|
||||||
LeaveCriticalSection(&This->cs);
|
LeaveCriticalSection(&This->cs);
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
@ -1732,7 +1757,7 @@ static HRESULT WINAPI MediaControl_Pause(IMediaControl *iface) {
|
||||||
This->position += time - This->start_time;
|
This->position += time - This->start_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
SendFilterMessage(iface, SendPause);
|
SendFilterMessage(iface, SendPause, 0);
|
||||||
This->state = State_Paused;
|
This->state = State_Paused;
|
||||||
LeaveCriticalSection(&This->cs);
|
LeaveCriticalSection(&This->cs);
|
||||||
return S_FALSE;
|
return S_FALSE;
|
||||||
|
@ -1752,8 +1777,8 @@ static HRESULT WINAPI MediaControl_Stop(IMediaControl *iface) {
|
||||||
This->position += time - This->start_time;
|
This->position += time - This->start_time;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (This->state == State_Running) SendFilterMessage(iface, SendPause);
|
if (This->state == State_Running) SendFilterMessage(iface, SendPause, 0);
|
||||||
SendFilterMessage(iface, SendStop);
|
SendFilterMessage(iface, SendStop, 0);
|
||||||
This->state = State_Stopped;
|
This->state = State_Stopped;
|
||||||
LeaveCriticalSection(&This->cs);
|
LeaveCriticalSection(&This->cs);
|
||||||
return S_OK;
|
return S_OK;
|
||||||
|
@ -1763,8 +1788,9 @@ static HRESULT WINAPI MediaControl_GetState(IMediaControl *iface,
|
||||||
LONG msTimeout,
|
LONG msTimeout,
|
||||||
OAFilterState *pfs) {
|
OAFilterState *pfs) {
|
||||||
ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
|
ICOM_THIS_MULTI(IFilterGraphImpl, IMediaControl_vtbl, iface);
|
||||||
|
DWORD end;
|
||||||
|
|
||||||
TRACE("(%p/%p)->(%d, %p): semi-stub !!!\n", This, iface, msTimeout, pfs);
|
TRACE("(%p/%p)->(%d, %p)\n", This, iface, msTimeout, pfs);
|
||||||
|
|
||||||
if (!pfs)
|
if (!pfs)
|
||||||
return E_POINTER;
|
return E_POINTER;
|
||||||
|
@ -1772,6 +1798,20 @@ static HRESULT WINAPI MediaControl_GetState(IMediaControl *iface,
|
||||||
EnterCriticalSection(&This->cs);
|
EnterCriticalSection(&This->cs);
|
||||||
|
|
||||||
*pfs = This->state;
|
*pfs = This->state;
|
||||||
|
if (msTimeout > 0)
|
||||||
|
{
|
||||||
|
end = GetTickCount() + msTimeout;
|
||||||
|
}
|
||||||
|
else if (msTimeout < 0)
|
||||||
|
{
|
||||||
|
end = INFINITE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
end = 0;
|
||||||
|
}
|
||||||
|
if (end)
|
||||||
|
SendFilterMessage(iface, SendGetState, end);
|
||||||
|
|
||||||
LeaveCriticalSection(&This->cs);
|
LeaveCriticalSection(&This->cs);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue