diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c index 1ed41bdcec5..1ef9c6e3afa 100644 --- a/dlls/quartz/filtergraph.c +++ b/dlls/quartz/filtergraph.c @@ -184,7 +184,9 @@ typedef struct _IFilterGraphImpl { LONG ref; IUnknown *punkFilterMapper2; struct list filters; - LONG nameIndex; + + unsigned int name_index; + IReferenceClock *refClock; IBaseFilter *refClockProvider; EventsQueue evqueue; @@ -554,74 +556,68 @@ static IBaseFilter *find_filter_by_name(IFilterGraphImpl *graph, const WCHAR *na } /*** IFilterGraph methods ***/ -static HRESULT WINAPI FilterGraph2_AddFilter(IFilterGraph2 *iface, IBaseFilter *pFilter, - LPCWSTR pName) +static HRESULT WINAPI FilterGraph2_AddFilter(IFilterGraph2 *iface, + IBaseFilter *filter, const WCHAR *name) { - IFilterGraphImpl *This = impl_from_IFilterGraph2(iface); - struct filter *entry; - HRESULT hr; - int j; - WCHAR* wszFilterName = NULL; + IFilterGraphImpl *graph = impl_from_IFilterGraph2(iface); BOOL duplicate_name = FALSE; + struct filter *entry; + unsigned int i; + HRESULT hr; - TRACE("(%p/%p)->(%p, %s (%p))\n", This, iface, pFilter, debugstr_w(pName), pName); + TRACE("graph %p, filter %p, name %s.\n", graph, filter, debugstr_w(name)); - if (!pFilter) + if (!filter) return E_POINTER; - wszFilterName = CoTaskMemAlloc( (pName ? lstrlenW(pName) + 6 : 5) * sizeof(WCHAR) ); - - if (pName && find_filter_by_name(This, pName)) - duplicate_name = TRUE; - - /* If no name given or name already existing, generate one */ - if (!pName || duplicate_name) - { - static const WCHAR wszFmt1[] = {'%','s',' ','%','0','4','d',0}; - static const WCHAR wszFmt2[] = {'%','0','4','d',0}; - - for (j = 0; j < 10000 ; j++) - { - /* Create name */ - if (pName) - swprintf(wszFilterName, pName ? lstrlenW(pName) + 6 : 5, wszFmt1, pName, This->nameIndex); - else - swprintf(wszFilterName, pName ? lstrlenW(pName) + 6 : 5, wszFmt2, This->nameIndex); - TRACE("Generated name %s\n", debugstr_w(wszFilterName)); - - if (This->nameIndex++ == 10000) - This->nameIndex = 1; - - if (!find_filter_by_name(This, wszFilterName)) - break; - } - /* Unable to find a suitable name */ - if (j == 10000) - { - CoTaskMemFree(wszFilterName); - return VFW_E_DUPLICATE_NAME; - } - } - else - memcpy(wszFilterName, pName, (lstrlenW(pName) + 1) * sizeof(WCHAR)); - - hr = IBaseFilter_JoinFilterGraph(pFilter, (IFilterGraph *)&This->IFilterGraph2_iface, wszFilterName); - if (FAILED(hr)) - { - CoTaskMemFree(wszFilterName); - return hr; - } - if (!(entry = heap_alloc(sizeof(*entry)))) + return E_OUTOFMEMORY; + + if (!(entry->name = CoTaskMemAlloc((name ? wcslen(name) + 6 : 5) * sizeof(WCHAR)))) { - CoTaskMemFree(wszFilterName); + heap_free(entry); return E_OUTOFMEMORY; } - IBaseFilter_AddRef(entry->filter = pFilter); - entry->name = wszFilterName; - list_add_head(&This->filters, &entry->entry); - This->version++; + if (name && find_filter_by_name(graph, name)) + duplicate_name = TRUE; + + if (!name || duplicate_name) + { + for (i = 0; i < 10000 ; ++i) + { + if (name) + swprintf(entry->name, name ? wcslen(name) + 6 : 5, L"%s %04u", name, graph->name_index); + else + swprintf(entry->name, name ? wcslen(name) + 6 : 5, L"%04u", graph->name_index); + + graph->name_index = (graph->name_index + 1) % 10000; + + if (!find_filter_by_name(graph, entry->name)) + break; + } + + if (i == 10000) + { + CoTaskMemFree(entry->name); + heap_free(entry); + return VFW_E_DUPLICATE_NAME; + } + } + else + wcscpy(entry->name, name); + + if (FAILED(hr = IBaseFilter_JoinFilterGraph(filter, + (IFilterGraph *)&graph->IFilterGraph2_iface, entry->name))) + { + CoTaskMemFree(entry->name); + heap_free(entry); + return hr; + } + + IBaseFilter_AddRef(entry->filter = filter); + list_add_head(&graph->filters, &entry->entry); + ++graph->version; return duplicate_name ? VFW_S_DUPLICATE_NAME : hr; } @@ -5706,7 +5702,7 @@ static HRESULT filter_graph_common_create(IUnknown *outer, void **out, BOOL thre fimpl->IGraphVersion_iface.lpVtbl = &IGraphVersion_VTable; fimpl->ref = 1; list_init(&fimpl->filters); - fimpl->nameIndex = 1; + fimpl->name_index = 1; fimpl->refClock = NULL; fimpl->hEventCompletion = CreateEventW(0, TRUE, FALSE, 0); fimpl->HandleEcComplete = TRUE;