[PATCH v4] quartz: Cache IMediaSeeking for filters.
Zebediah Figura
z.figura12 at gmail.com
Wed Apr 8 14:38:14 CDT 2020
From: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Signed-off-by: Gabriel Ivăncescu <gabrielopcode at gmail.com>
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
This supersedes patch 183026.
v4: Add a more detailed comment to the code, instead of in the commit message.
dlls/quartz/filtergraph.c | 47 ++++++++++++++++++---------------------
1 file changed, 22 insertions(+), 25 deletions(-)
diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c
index c659cf96e4c..7a9db402ec3 100644
--- a/dlls/quartz/filtergraph.c
+++ b/dlls/quartz/filtergraph.c
@@ -153,6 +153,7 @@ struct filter
{
struct list entry, sorted_entry;
IBaseFilter *filter;
+ IMediaSeeking *seeking;
WCHAR *name;
BOOL sorting;
};
@@ -593,24 +594,19 @@ static BOOL has_output_pins(IBaseFilter *filter)
return FALSE;
}
-static BOOL is_renderer(IBaseFilter *filter)
+static BOOL is_renderer(struct filter *filter)
{
IAMFilterMiscFlags *flags;
- IMediaSeeking *seeking;
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)
ret = TRUE;
IAMFilterMiscFlags_Release(flags);
}
- else if (SUCCEEDED(IBaseFilter_QueryInterface(filter, &IID_IMediaSeeking, (void **)&seeking)))
- {
- IMediaSeeking_Release(seeking);
- if (!has_output_pins(filter))
- ret = TRUE;
- }
+ else if (filter->seeking && !has_output_pins(filter->filter))
+ ret = TRUE;
return ret;
}
@@ -675,12 +671,19 @@ static HRESULT WINAPI FilterGraph2_AddFilter(IFilterGraph2 *iface,
}
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->sorted_filters, &entry->sorted_entry);
entry->sorting = FALSE;
++graph->version;
- if (is_renderer(filter))
+ if (is_renderer(entry))
++graph->nRenderers;
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);
if (SUCCEEDED(hr))
{
- if (is_renderer(pFilter))
+ if (is_renderer(entry))
--This->nRenderers;
IBaseFilter_SetSyncSource(pFilter, NULL);
IBaseFilter_Release(pFilter);
+ if (entry->seeking)
+ IMediaSeeking_Release(entry->seeking);
list_remove(&entry->entry);
list_remove(&entry->sorted_entry);
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)
{
- IMediaSeeking *seek = NULL;
-
- IBaseFilter_QueryInterface(filter->filter, &IID_IMediaSeeking, (void **)&seek);
- if (!seek)
+ if (!filter->seeking)
continue;
- hr = FoundSeek(This, seek, arg);
- IMediaSeeking_Release(seek);
+ hr = FoundSeek(This, filter->seeking, arg);
if (hr_return != E_NOTIMPL)
allnotimpl = FALSE;
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);
HRESULT hr = E_NOTIMPL, filter_hr;
- IMediaSeeking *seeking;
struct filter *filter;
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)
{
- if (FAILED(IBaseFilter_QueryInterface(filter->filter, &IID_IMediaSeeking, (void **)&seeking)))
+ if (!filter->seeking)
continue;
- filter_hr = IMediaSeeking_GetStopPosition(seeking, &filter_stop);
- IMediaSeeking_Release(seeking);
+ filter_hr = IMediaSeeking_GetStopPosition(filter->seeking, &filter_stop);
if (SUCCEEDED(filter_hr))
{
hr = S_OK;
@@ -2507,7 +2506,6 @@ static HRESULT WINAPI MediaSeeking_SetPositions(IMediaSeeking *iface, LONGLONG *
{
IFilterGraphImpl *graph = impl_from_IMediaSeeking(iface);
HRESULT hr = E_NOTIMPL, filter_hr;
- IMediaSeeking *seeking;
struct filter *filter;
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;
- if (FAILED(IBaseFilter_QueryInterface(filter->filter, &IID_IMediaSeeking, (void **)&seeking)))
+ if (!filter->seeking)
continue;
- filter_hr = IMediaSeeking_SetPositions(seeking, ¤t,
+ filter_hr = IMediaSeeking_SetPositions(filter->seeking, ¤t,
current_flags | AM_SEEKING_ReturnTime, &stop, stop_flags);
- IMediaSeeking_Release(seeking);
if (SUCCEEDED(filter_hr))
{
hr = S_OK;
--
2.26.0
More information about the wine-devel
mailing list