quartz: Cache IMediaSeeking for filters.
Signed-off-by: Gabriel Ivăncescu <gabrielopcode@gmail.com> Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
2cc0116da0
commit
0320f165c8
|
@ -153,6 +153,7 @@ struct filter
|
||||||
{
|
{
|
||||||
struct list entry, sorted_entry;
|
struct list entry, sorted_entry;
|
||||||
IBaseFilter *filter;
|
IBaseFilter *filter;
|
||||||
|
IMediaSeeking *seeking;
|
||||||
WCHAR *name;
|
WCHAR *name;
|
||||||
BOOL sorting;
|
BOOL sorting;
|
||||||
};
|
};
|
||||||
|
@ -593,24 +594,19 @@ static BOOL has_output_pins(IBaseFilter *filter)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL is_renderer(IBaseFilter *filter)
|
static BOOL is_renderer(struct filter *filter)
|
||||||
{
|
{
|
||||||
IAMFilterMiscFlags *flags;
|
IAMFilterMiscFlags *flags;
|
||||||
IMediaSeeking *seeking;
|
|
||||||
BOOL ret = FALSE;
|
BOOL ret = FALSE;
|
||||||
|
|
||||||
if (SUCCEEDED(IBaseFilter_QueryInterface(filter, &IID_IAMFilterMiscFlags, (void **)&flags)))
|
if (SUCCEEDED(IBaseFilter_QueryInterface(filter->filter, &IID_IAMFilterMiscFlags, (void **)&flags)))
|
||||||
{
|
{
|
||||||
if (IAMFilterMiscFlags_GetMiscFlags(flags) & AM_FILTER_MISC_FLAGS_IS_RENDERER)
|
if (IAMFilterMiscFlags_GetMiscFlags(flags) & AM_FILTER_MISC_FLAGS_IS_RENDERER)
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
IAMFilterMiscFlags_Release(flags);
|
IAMFilterMiscFlags_Release(flags);
|
||||||
}
|
}
|
||||||
else if (SUCCEEDED(IBaseFilter_QueryInterface(filter, &IID_IMediaSeeking, (void **)&seeking)))
|
else if (filter->seeking && !has_output_pins(filter->filter))
|
||||||
{
|
|
||||||
IMediaSeeking_Release(seeking);
|
|
||||||
if (!has_output_pins(filter))
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
}
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -675,12 +671,19 @@ static HRESULT WINAPI FilterGraph2_AddFilter(IFilterGraph2 *iface,
|
||||||
}
|
}
|
||||||
|
|
||||||
IBaseFilter_AddRef(entry->filter = filter);
|
IBaseFilter_AddRef(entry->filter = filter);
|
||||||
|
|
||||||
|
/* The Legend of Heroes: Trails of Cold Steel II destroys its filter when
|
||||||
|
* its IMediaSeeking interface is released, so cache the interface instead
|
||||||
|
* of querying for it every time. */
|
||||||
|
if (FAILED(IBaseFilter_QueryInterface(filter, &IID_IMediaSeeking, (void **)&entry->seeking)))
|
||||||
|
entry->seeking = NULL;
|
||||||
|
|
||||||
list_add_head(&graph->filters, &entry->entry);
|
list_add_head(&graph->filters, &entry->entry);
|
||||||
list_add_head(&graph->sorted_filters, &entry->sorted_entry);
|
list_add_head(&graph->sorted_filters, &entry->sorted_entry);
|
||||||
entry->sorting = FALSE;
|
entry->sorting = FALSE;
|
||||||
++graph->version;
|
++graph->version;
|
||||||
|
|
||||||
if (is_renderer(filter))
|
if (is_renderer(entry))
|
||||||
++graph->nRenderers;
|
++graph->nRenderers;
|
||||||
|
|
||||||
return duplicate_name ? VFW_S_DUPLICATE_NAME : hr;
|
return duplicate_name ? VFW_S_DUPLICATE_NAME : hr;
|
||||||
|
@ -755,11 +758,13 @@ static HRESULT WINAPI FilterGraph2_RemoveFilter(IFilterGraph2 *iface, IBaseFilte
|
||||||
hr = IBaseFilter_JoinFilterGraph(pFilter, NULL, NULL);
|
hr = IBaseFilter_JoinFilterGraph(pFilter, NULL, NULL);
|
||||||
if (SUCCEEDED(hr))
|
if (SUCCEEDED(hr))
|
||||||
{
|
{
|
||||||
if (is_renderer(pFilter))
|
if (is_renderer(entry))
|
||||||
--This->nRenderers;
|
--This->nRenderers;
|
||||||
|
|
||||||
IBaseFilter_SetSyncSource(pFilter, NULL);
|
IBaseFilter_SetSyncSource(pFilter, NULL);
|
||||||
IBaseFilter_Release(pFilter);
|
IBaseFilter_Release(pFilter);
|
||||||
|
if (entry->seeking)
|
||||||
|
IMediaSeeking_Release(entry->seeking);
|
||||||
list_remove(&entry->entry);
|
list_remove(&entry->entry);
|
||||||
list_remove(&entry->sorted_entry);
|
list_remove(&entry->sorted_entry);
|
||||||
CoTaskMemFree(entry->name);
|
CoTaskMemFree(entry->name);
|
||||||
|
@ -2219,13 +2224,9 @@ static HRESULT all_renderers_seek(IFilterGraphImpl *This, fnFoundSeek FoundSeek,
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY(filter, &This->filters, struct filter, entry)
|
LIST_FOR_EACH_ENTRY(filter, &This->filters, struct filter, entry)
|
||||||
{
|
{
|
||||||
IMediaSeeking *seek = NULL;
|
if (!filter->seeking)
|
||||||
|
|
||||||
IBaseFilter_QueryInterface(filter->filter, &IID_IMediaSeeking, (void **)&seek);
|
|
||||||
if (!seek)
|
|
||||||
continue;
|
continue;
|
||||||
hr = FoundSeek(This, seek, arg);
|
hr = FoundSeek(This, filter->seeking, arg);
|
||||||
IMediaSeeking_Release(seek);
|
|
||||||
if (hr_return != E_NOTIMPL)
|
if (hr_return != E_NOTIMPL)
|
||||||
allnotimpl = FALSE;
|
allnotimpl = FALSE;
|
||||||
if (hr_return == S_OK || (FAILED(hr) && hr != E_NOTIMPL && SUCCEEDED(hr_return)))
|
if (hr_return == S_OK || (FAILED(hr) && hr != E_NOTIMPL && SUCCEEDED(hr_return)))
|
||||||
|
@ -2414,7 +2415,6 @@ static HRESULT WINAPI MediaSeeking_GetStopPosition(IMediaSeeking *iface, LONGLON
|
||||||
{
|
{
|
||||||
IFilterGraphImpl *graph = impl_from_IMediaSeeking(iface);
|
IFilterGraphImpl *graph = impl_from_IMediaSeeking(iface);
|
||||||
HRESULT hr = E_NOTIMPL, filter_hr;
|
HRESULT hr = E_NOTIMPL, filter_hr;
|
||||||
IMediaSeeking *seeking;
|
|
||||||
struct filter *filter;
|
struct filter *filter;
|
||||||
LONGLONG filter_stop;
|
LONGLONG filter_stop;
|
||||||
|
|
||||||
|
@ -2429,11 +2429,10 @@ static HRESULT WINAPI MediaSeeking_GetStopPosition(IMediaSeeking *iface, LONGLON
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY(filter, &graph->filters, struct filter, entry)
|
LIST_FOR_EACH_ENTRY(filter, &graph->filters, struct filter, entry)
|
||||||
{
|
{
|
||||||
if (FAILED(IBaseFilter_QueryInterface(filter->filter, &IID_IMediaSeeking, (void **)&seeking)))
|
if (!filter->seeking)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
filter_hr = IMediaSeeking_GetStopPosition(seeking, &filter_stop);
|
filter_hr = IMediaSeeking_GetStopPosition(filter->seeking, &filter_stop);
|
||||||
IMediaSeeking_Release(seeking);
|
|
||||||
if (SUCCEEDED(filter_hr))
|
if (SUCCEEDED(filter_hr))
|
||||||
{
|
{
|
||||||
hr = S_OK;
|
hr = S_OK;
|
||||||
|
@ -2507,7 +2506,6 @@ static HRESULT WINAPI MediaSeeking_SetPositions(IMediaSeeking *iface, LONGLONG *
|
||||||
{
|
{
|
||||||
IFilterGraphImpl *graph = impl_from_IMediaSeeking(iface);
|
IFilterGraphImpl *graph = impl_from_IMediaSeeking(iface);
|
||||||
HRESULT hr = E_NOTIMPL, filter_hr;
|
HRESULT hr = E_NOTIMPL, filter_hr;
|
||||||
IMediaSeeking *seeking;
|
|
||||||
struct filter *filter;
|
struct filter *filter;
|
||||||
FILTER_STATE state;
|
FILTER_STATE state;
|
||||||
|
|
||||||
|
@ -2539,12 +2537,11 @@ static HRESULT WINAPI MediaSeeking_SetPositions(IMediaSeeking *iface, LONGLONG *
|
||||||
{
|
{
|
||||||
LONGLONG current = current_ptr ? *current_ptr : 0, stop = stop_ptr ? *stop_ptr : 0;
|
LONGLONG current = current_ptr ? *current_ptr : 0, stop = stop_ptr ? *stop_ptr : 0;
|
||||||
|
|
||||||
if (FAILED(IBaseFilter_QueryInterface(filter->filter, &IID_IMediaSeeking, (void **)&seeking)))
|
if (!filter->seeking)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
filter_hr = IMediaSeeking_SetPositions(seeking, ¤t,
|
filter_hr = IMediaSeeking_SetPositions(filter->seeking, ¤t,
|
||||||
current_flags | AM_SEEKING_ReturnTime, &stop, stop_flags);
|
current_flags | AM_SEEKING_ReturnTime, &stop, stop_flags);
|
||||||
IMediaSeeking_Release(seeking);
|
|
||||||
if (SUCCEEDED(filter_hr))
|
if (SUCCEEDED(filter_hr))
|
||||||
{
|
{
|
||||||
hr = S_OK;
|
hr = S_OK;
|
||||||
|
|
Loading…
Reference in New Issue