Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/main.c | 457 ++++++++++++++++++++++++++++++------- dlls/mfplat/mfplat.spec | 1 + dlls/mfplat/tests/mfplat.c | 17 +- include/mfapi.h | 2 + 4 files changed, 391 insertions(+), 86 deletions(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index ef0db5a276..45cddd42cc 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -85,7 +85,7 @@ static CRITICAL_SECTION local_handlers_section = { NULL, -1, 0, 0, 0, 0 }; static struct list local_scheme_handlers = LIST_INIT(local_scheme_handlers); static struct list local_bytestream_handlers = LIST_INIT(local_bytestream_handlers);
-struct local_mft +struct mft_registration { struct list entry; IClassFactory *factory; @@ -107,6 +107,7 @@ struct transform_activate { struct attributes attributes; IMFActivate IMFActivate_iface; + IClassFactory *factory; };
struct system_clock @@ -194,6 +195,8 @@ static ULONG WINAPI transform_activate_Release(IMFActivate *iface) if (!refcount) { clear_attributes_object(&activate->attributes); + if (activate->factory) + IClassFactory_Release(activate->factory); heap_free(activate); }
@@ -537,13 +540,11 @@ static const IMFActivateVtbl transform_activate_vtbl = transform_activate_DetachObject, };
-HRESULT WINAPI MFCreateTransformActivate(IMFActivate **activate) +static HRESULT create_transform_activate(IClassFactory *factory, IMFActivate **activate) { struct transform_activate *object; HRESULT hr;
- TRACE("%p.\n", activate); - object = heap_alloc_zero(sizeof(*object)); if (!object) return E_OUTOFMEMORY; @@ -555,12 +556,22 @@ HRESULT WINAPI MFCreateTransformActivate(IMFActivate **activate) }
object->IMFActivate_iface.lpVtbl = &transform_activate_vtbl; + object->factory = factory; + if (object->factory) + IClassFactory_AddRef(object->factory);
*activate = &object->IMFActivate_iface;
return S_OK; }
+HRESULT WINAPI MFCreateTransformActivate(IMFActivate **activate) +{ + TRACE("%p.\n", activate); + + return create_transform_activate(NULL, activate); +} + static const WCHAR transform_keyW[] = {'M','e','d','i','a','F','o','u','n','d','a','t','i','o','n','\', 'T','r','a','n','s','f','o','r','m','s',0}; static const WCHAR categories_keyW[] = {'M','e','d','i','a','F','o','u','n','d','a','t','i','o','n','\', @@ -648,7 +659,7 @@ static BOOL GUIDFromString(LPCWSTR s, GUID *id) id->Data4[(i-19)/2] = guid_conv_table[s[i]] << 4 | guid_conv_table[s[i+1]]; }
- if (!s[37]) return TRUE; + if (!s[36]) return TRUE; return FALSE; }
@@ -774,7 +785,7 @@ HRESULT WINAPI MFTRegister(CLSID clsid, GUID category, LPWSTR name, UINT32 flags return hr; }
-static void release_local_mft(struct local_mft *mft) +static void release_mft_registration(struct mft_registration *mft) { if (mft->factory) IClassFactory_Release(mft->factory); @@ -788,7 +799,7 @@ static HRESULT mft_register_local(IClassFactory *factory, REFCLSID clsid, REFGUI UINT32 input_count, const MFT_REGISTER_TYPE_INFO *input_types, UINT32 output_count, const MFT_REGISTER_TYPE_INFO *output_types) { - struct local_mft *mft, *cur, *unreg_mft = NULL; + struct mft_registration *mft, *cur, *unreg_mft = NULL; HRESULT hr;
if (!factory && !clsid) @@ -807,7 +818,7 @@ static HRESULT mft_register_local(IClassFactory *factory, REFCLSID clsid, REFGUI if (clsid) mft->clsid = *clsid; mft->category = *category; - mft->flags = flags; + mft->flags = flags | MFT_ENUM_FLAG_LOCALMFT; if (FAILED(hr = heap_strdupW(name, &mft->name))) goto failed;
@@ -835,7 +846,7 @@ static HRESULT mft_register_local(IClassFactory *factory, REFCLSID clsid, REFGUI
EnterCriticalSection(&local_mfts_section);
- LIST_FOR_EACH_ENTRY(cur, &local_mfts, struct local_mft, entry) + LIST_FOR_EACH_ENTRY(cur, &local_mfts, struct mft_registration, entry) { if (cur->factory == factory) { @@ -849,11 +860,11 @@ static HRESULT mft_register_local(IClassFactory *factory, REFCLSID clsid, REFGUI LeaveCriticalSection(&local_mfts_section);
if (unreg_mft) - release_local_mft(unreg_mft); + release_mft_registration(unreg_mft);
failed: if (FAILED(hr)) - release_local_mft(mft); + release_mft_registration(mft);
return hr; } @@ -880,7 +891,7 @@ HRESULT WINAPI MFTRegisterLocalByCLSID(REFCLSID clsid, REFGUID category, LPCWSTR
static HRESULT mft_unregister_local(IClassFactory *factory, REFCLSID clsid) { - struct local_mft *cur, *cur2; + struct mft_registration *cur, *cur2; BOOL unregister_all = !factory && !clsid; struct list unreg;
@@ -888,7 +899,7 @@ static HRESULT mft_unregister_local(IClassFactory *factory, REFCLSID clsid)
EnterCriticalSection(&local_mfts_section);
- LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &local_mfts, struct local_mft, entry) + LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &local_mfts, struct mft_registration, entry) { if (!unregister_all) { @@ -911,10 +922,10 @@ static HRESULT mft_unregister_local(IClassFactory *factory, REFCLSID clsid) if (!unregister_all && list_empty(&unreg)) return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
- LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &unreg, struct local_mft, entry) + LIST_FOR_EACH_ENTRY_SAFE(cur, cur2, &unreg, struct mft_registration, entry) { list_remove(&cur->entry); - release_local_mft(cur); + release_mft_registration(cur); }
return S_OK; @@ -945,135 +956,411 @@ MFTIME WINAPI MFGetSystemTime(void) return mf; }
-static BOOL match_type(const WCHAR *clsid_str, const WCHAR *type_str, MFT_REGISTER_TYPE_INFO *type) +static BOOL mft_is_type_info_match(struct mft_registration *mft, const GUID *category, UINT32 flags, + IMFPluginControl *plugin_control, const MFT_REGISTER_TYPE_INFO *input_type, + const MFT_REGISTER_TYPE_INFO *output_type) +{ + BOOL matching = TRUE; + DWORD model; + int i; + + if (!IsEqualGUID(category, &mft->category)) + return FALSE; + + /* Default model is synchronous. */ + model = mft->flags & (MFT_ENUM_FLAG_SYNCMFT | MFT_ENUM_FLAG_ASYNCMFT | MFT_ENUM_FLAG_HARDWARE); + if (!model) + model = MFT_ENUM_FLAG_SYNCMFT; + if (!(model & flags & (MFT_ENUM_FLAG_SYNCMFT | MFT_ENUM_FLAG_ASYNCMFT | MFT_ENUM_FLAG_HARDWARE))) + return FALSE; + + /* These flags should be explicitly enabled. */ + if (mft->flags & ~flags & (MFT_ENUM_FLAG_FIELDOFUSE | MFT_ENUM_FLAG_TRANSCODE_ONLY)) + return FALSE; + + if (flags & MFT_ENUM_FLAG_SORTANDFILTER && !mft->factory && plugin_control + && IMFPluginControl_IsDisabled(plugin_control, MF_Plugin_Type_MFT, &mft->clsid) == S_OK) + { + return FALSE; + } + + if (input_type) + { + for (i = 0, matching = FALSE; input_type && i < mft->input_types_count; ++i) + { + if (!memcmp(&mft->input_types[i], input_type, sizeof(*input_type))) + { + matching = TRUE; + break; + } + } + } + + if (output_type && matching) + { + for (i = 0, matching = FALSE; i < mft->output_types_count; ++i) + { + if (!memcmp(&mft->output_types[i], output_type, sizeof(*output_type))) + { + matching = TRUE; + break; + } + } + } + + return matching; +} + +static void mft_get_reg_type_info(const WCHAR *clsidW, const WCHAR *typeW, MFT_REGISTER_TYPE_INFO **type, + UINT32 *count) { HKEY htransform, hfilter; DWORD reg_type, size; - LONG ret = FALSE; - MFT_REGISTER_TYPE_INFO *info = NULL; - int i; + + *type = NULL; + *count = 0;
if (RegOpenKeyW(HKEY_CLASSES_ROOT, transform_keyW, &htransform)) - return FALSE; + return;
- if (RegOpenKeyW(htransform, clsid_str, &hfilter)) + if (RegOpenKeyW(htransform, clsidW, &hfilter)) { RegCloseKey(htransform); - return FALSE; + return; }
- if (RegQueryValueExW(hfilter, type_str, NULL, ®_type, NULL, &size) != ERROR_SUCCESS) + if (RegQueryValueExW(hfilter, typeW, NULL, ®_type, NULL, &size)) goto out;
if (reg_type != REG_BINARY) goto out;
- if (!size || size % (sizeof(MFT_REGISTER_TYPE_INFO)) != 0) + if (!size || size % sizeof(**type)) goto out;
- info = HeapAlloc(GetProcessHeap(), 0, size); - if (!info) + if (!(*type = heap_alloc(size))) goto out;
- if (RegQueryValueExW(hfilter, type_str, NULL, ®_type, (LPBYTE)info, &size) != ERROR_SUCCESS) - goto out; + *count = size / sizeof(**type);
- for (i = 0; i < size / sizeof(MFT_REGISTER_TYPE_INFO); i++) + if (RegQueryValueExW(hfilter, typeW, NULL, ®_type, (BYTE *)*type, &size)) { - if (IsEqualGUID(&info[i].guidMajorType, &type->guidMajorType) && - IsEqualGUID(&info[i].guidSubtype, &type->guidSubtype)) - { - ret = TRUE; - break; - } + heap_free(*type); + *type = NULL; + *count = 0; }
out: - HeapFree(GetProcessHeap(), 0, info); RegCloseKey(hfilter); RegCloseKey(htransform); - return ret; }
-/*********************************************************************** - * MFTEnum (mfplat.@) - */ -HRESULT WINAPI MFTEnum(GUID category, UINT32 flags, MFT_REGISTER_TYPE_INFO *input_type, - MFT_REGISTER_TYPE_INFO *output_type, IMFAttributes *attributes, - CLSID **pclsids, UINT32 *pcount) +static void mft_get_reg_flags(const WCHAR *clsidW, const WCHAR *nameW, DWORD *flags) { - WCHAR buffer[64], clsid_str[MAX_PATH] = {0}; - HKEY hcategory, hlist; - DWORD index = 0; - DWORD size = MAX_PATH; - CLSID *clsids = NULL; - UINT32 count = 0; - LONG ret; + DWORD ret, reg_type, size; + HKEY hroot, hmft;
- TRACE("(%s, %x, %p, %p, %p, %p, %p)\n", debugstr_guid(&category), flags, input_type, - output_type, attributes, pclsids, pcount); + *flags = 0;
- if (!pclsids || !pcount) - return E_INVALIDARG; + if (RegOpenKeyW(HKEY_CLASSES_ROOT, transform_keyW, &hroot)) + return; + + ret = RegOpenKeyW(hroot, clsidW, &hmft); + RegCloseKey(hroot); + if (ret) + return; + + reg_type = 0; + if (!RegQueryValueExW(hmft, nameW, NULL, ®_type, NULL, &size) && reg_type == REG_DWORD) + RegQueryValueExW(hmft, nameW, NULL, ®_type, (BYTE *)flags, &size); + + RegCloseKey(hmft); +} + +static HRESULT mft_collect_machine_reg(struct list *mfts, const GUID *category, UINT32 flags, + IMFPluginControl *plugin_control, const MFT_REGISTER_TYPE_INFO *input_type, + const MFT_REGISTER_TYPE_INFO *output_type) +{ + struct mft_registration mft, *cur; + HKEY hcategory, hlist; + WCHAR clsidW[64]; + DWORD ret, size; + int index = 0;
if (RegOpenKeyW(HKEY_CLASSES_ROOT, categories_keyW, &hcategory)) return E_FAIL;
- GUIDToString(buffer, &category); - - ret = RegOpenKeyW(hcategory, buffer, &hlist); + GUIDToString(clsidW, category); + ret = RegOpenKeyW(hcategory, clsidW, &hlist); RegCloseKey(hcategory); - if (ret) return E_FAIL; + if (ret) + return E_FAIL;
- while (RegEnumKeyExW(hlist, index, clsid_str, &size, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) + size = ARRAY_SIZE(clsidW); + while (!RegEnumKeyExW(hlist, index, clsidW, &size, NULL, NULL, NULL, NULL)) { - GUID clsid; - void *tmp; - - if (!GUIDFromString(clsid_str, &clsid)) + memset(&mft, 0, sizeof(mft)); + mft.category = *category; + if (!GUIDFromString(clsidW, &mft.clsid)) goto next;
- if (output_type && !match_type(clsid_str, outputtypesW, output_type)) - goto next; + mft_get_reg_flags(clsidW, mftflagsW, &mft.flags);
- if (input_type && !match_type(clsid_str, inputtypesW, input_type)) - goto next; + if (output_type) + mft_get_reg_type_info(clsidW, outputtypesW, &mft.output_types, &mft.output_types_count); + + if (input_type) + mft_get_reg_type_info(clsidW, inputtypesW, &mft.input_types, &mft.input_types_count);
- tmp = CoTaskMemRealloc(clsids, (count + 1) * sizeof(GUID)); - if (!tmp) + if (!mft_is_type_info_match(&mft, category, flags, plugin_control, input_type, output_type)) { - CoTaskMemFree(clsids); - RegCloseKey(hlist); - return E_OUTOFMEMORY; + heap_free(mft.input_types); + heap_free(mft.output_types); + goto next; }
- clsids = tmp; - clsids[count++] = clsid; + cur = heap_alloc(sizeof(*cur)); + /* Reuse allocated type arrays. */ + *cur = mft; + list_add_tail(mfts, &cur->entry);
next: - size = MAX_PATH; + size = ARRAY_SIZE(clsidW); index++; }
- *pclsids = clsids; - *pcount = count; - - RegCloseKey(hlist); return S_OK; }
+static BOOL mft_is_preferred(IMFPluginControl *plugin_control, const CLSID *clsid) +{ + CLSID preferred; + WCHAR *selector; + int index = 0; + + while (SUCCEEDED(IMFPluginControl_GetPreferredClsidByIndex(plugin_control, MF_Plugin_Type_MFT, index++, &selector, + &preferred))) + { + CoTaskMemFree(selector); + + if (IsEqualGUID(&preferred, clsid)) + return TRUE; + } + + return FALSE; +} + +static HRESULT mft_enum(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INFO *input_type, + const MFT_REGISTER_TYPE_INFO *output_type, IMFAttributes *attributes, IMFActivate ***activate, UINT32 *count) +{ + IMFPluginControl *plugin_control = NULL; + struct list mfts, mfts_sorted, *result = &mfts; + struct mft_registration *mft, *mft2; + unsigned int obj_count; + HRESULT hr; + + *count = 0; + *activate = NULL; + + if (!flags) + flags = MFT_ENUM_FLAG_SYNCMFT | MFT_ENUM_FLAG_LOCALMFT | MFT_ENUM_FLAG_SORTANDFILTER; + + /* Synchronous processing is default. */ + if (!(flags & (MFT_ENUM_FLAG_SYNCMFT | MFT_ENUM_FLAG_ASYNCMFT | MFT_ENUM_FLAG_HARDWARE))) + flags |= MFT_ENUM_FLAG_SYNCMFT; + + if (FAILED(hr = MFGetPluginControl(&plugin_control))) + { + WARN("Failed to get plugin control instance, hr %#x.\n", hr); + return hr; + } + + list_init(&mfts); + + /* Collect from registry */ + mft_collect_machine_reg(&mfts, &category, flags, plugin_control, input_type, output_type); + + /* Collect locally registered ones. */ + if (flags & MFT_ENUM_FLAG_LOCALMFT) + { + struct mft_registration *local; + + EnterCriticalSection(&local_mfts_section); + + LIST_FOR_EACH_ENTRY(local, &local_mfts, struct mft_registration, entry) + { + if (mft_is_type_info_match(local, &category, flags, plugin_control, input_type, output_type)) + { + mft = heap_alloc_zero(sizeof(*mft)); + + mft->clsid = local->clsid; + mft->factory = local->factory; + if (mft->factory) + IClassFactory_AddRef(mft->factory); + mft->flags = local->flags; + + list_add_tail(&mfts, &mft->entry); + } + } + + LeaveCriticalSection(&local_mfts_section); + } + + list_init(&mfts_sorted); + + if (flags & MFT_ENUM_FLAG_SORTANDFILTER) + { + /* Local registrations. */ + LIST_FOR_EACH_ENTRY_SAFE(mft, mft2, &mfts, struct mft_registration, entry) + { + if (mft->flags & MFT_ENUM_FLAG_LOCALMFT) + { + list_remove(&mft->entry); + list_add_tail(&mfts_sorted, &mft->entry); + } + } + + /* FIXME: Sort by merit value, for the ones that got it. Currently not handled. */ + + /* Preferred transforms. */ + LIST_FOR_EACH_ENTRY_SAFE(mft, mft2, &mfts, struct mft_registration, entry) + { + if (!mft->factory && mft_is_preferred(plugin_control, &mft->clsid)) + { + list_remove(&mft->entry); + list_add_tail(&mfts_sorted, &mft->entry); + } + } + + /* Append the rest. */ + LIST_FOR_EACH_ENTRY_SAFE(mft, mft2, &mfts, struct mft_registration, entry) + { + list_remove(&mft->entry); + list_add_tail(&mfts_sorted, &mft->entry); + } + + result = &mfts; + } + + IMFPluginControl_Release(plugin_control); + + /* Create activation objects from CLSID/IClassFactory. */ + + obj_count = list_count(result); + + if (obj_count) + { + if (!(*activate = CoTaskMemAlloc(obj_count * sizeof(**activate)))) + hr = E_OUTOFMEMORY; + + obj_count = 0; + + LIST_FOR_EACH_ENTRY_SAFE(mft, mft2, result, struct mft_registration, entry) + { + IMFActivate *mft_activate; + + if (*activate) + { + if (SUCCEEDED(create_transform_activate(mft->factory, &mft_activate))) + { + (*activate)[obj_count] = mft_activate; + + /* FIXME: set some attributes */ + + obj_count++; + } + } + + list_remove(&mft->entry); + release_mft_registration(mft); + } + } + + if (!obj_count) + { + CoTaskMemFree(*activate); + *activate = NULL; + } + *count = obj_count; + + return hr; +} + +/*********************************************************************** + * MFTEnum (mfplat.@) + */ +HRESULT WINAPI MFTEnum(GUID category, UINT32 flags, MFT_REGISTER_TYPE_INFO *input_type, + MFT_REGISTER_TYPE_INFO *output_type, IMFAttributes *attributes, CLSID **clsids, UINT32 *count) +{ + struct mft_registration *mft, *mft2; + unsigned int mft_count; + struct list mfts; + HRESULT hr; + + TRACE("%s, %#x, %p, %p, %p, %p, %p.\n", debugstr_guid(&category), flags, input_type, output_type, attributes, + clsids, count); + + if (!clsids || !count) + return E_INVALIDARG; + + *count = 0; + + list_init(&mfts); + + if (FAILED(hr = mft_collect_machine_reg(&mfts, &category, MFT_ENUM_FLAG_SYNCMFT, NULL, input_type, output_type))) + return hr; + + mft_count = list_count(&mfts); + + if (mft_count) + { + if (!(*clsids = CoTaskMemAlloc(mft_count * sizeof(**clsids)))) + hr = E_OUTOFMEMORY; + + mft_count = 0; + LIST_FOR_EACH_ENTRY_SAFE(mft, mft2, &mfts, struct mft_registration, entry) + { + if (*clsids) + (*clsids)[mft_count++] = mft->clsid; + list_remove(&mft->entry); + release_mft_registration(mft); + } + } + + if (!mft_count) + { + CoTaskMemFree(*clsids); + *clsids = NULL; + } + *count = mft_count; + + return hr; +} + /*********************************************************************** * MFTEnumEx (mfplat.@) */ HRESULT WINAPI MFTEnumEx(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INFO *input_type, - const MFT_REGISTER_TYPE_INFO *output_type, IMFActivate ***activate, - UINT32 *pcount) + const MFT_REGISTER_TYPE_INFO *output_type, IMFActivate ***activate, UINT32 *count) { - FIXME("(%s, %x, %p, %p, %p, %p): stub\n", debugstr_guid(&category), flags, input_type, - output_type, activate, pcount); + TRACE("%s, %#x, %p, %p, %p, %p.\n", debugstr_guid(&category), flags, input_type, output_type, activate, count);
- *pcount = 0; - return S_OK; + return mft_enum(category, flags, input_type, output_type, NULL, activate, count); +} + +/*********************************************************************** + * MFTEnum2 (mfplat.@) + */ +HRESULT WINAPI MFTEnum2(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INFO *input_type, + const MFT_REGISTER_TYPE_INFO *output_type, IMFAttributes *attributes, IMFActivate ***activate, UINT32 *count) +{ + TRACE("%s, %#x, %p, %p, %p, %p, %p.\n", debugstr_guid(&category), flags, input_type, output_type, attributes, + activate, count); + + if (attributes) + FIXME("Ignoring attributes.\n"); + + return mft_enum(category, flags, input_type, output_type, attributes, activate, count); }
/*********************************************************************** diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec index 85e28792c6..7e3bd4571c 100644 --- a/dlls/mfplat/mfplat.spec +++ b/dlls/mfplat/mfplat.spec @@ -144,6 +144,7 @@ @ stdcall MFStartup(long long) @ stub MFStreamDescriptorProtectMediaType @ stdcall MFTEnum(int128 long ptr ptr ptr ptr ptr) +@ stdcall MFTEnum2(int128 long ptr ptr ptr ptr ptr) @ stdcall MFTEnumEx(int128 long ptr ptr ptr ptr) @ stub MFTGetInfo @ stdcall MFTRegister(int128 int128 wstr long long ptr long ptr ptr) diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 896cd93a46..a93bbfe7f1 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -89,6 +89,8 @@ static HRESULT (WINAPI *pMFTRegisterLocalByCLSID)(REFCLSID clsid, REFGUID catego static HRESULT (WINAPI *pMFTUnregisterLocal)(IClassFactory *factory); static HRESULT (WINAPI *pMFTUnregisterLocalByCLSID)(CLSID clsid); static HRESULT (WINAPI *pMFAllocateWorkQueueEx)(MFASYNC_WORKQUEUE_TYPE queue_type, DWORD *queue); +static HRESULT (WINAPI *pMFTEnumEx)(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INFO *input_type, + const MFT_REGISTER_TYPE_INFO *output_type, IMFActivate ***activate, UINT32 *count);
static const WCHAR fileschemeW[] = L"file://";
@@ -659,13 +661,14 @@ static void init_functions(void) X(MFCreateDXGIDeviceManager); X(MFCreateSourceResolver); X(MFCreateMFByteStreamOnStream); + X(MFCreateTransformActivate); X(MFHeapAlloc); X(MFHeapFree); X(MFPutWaitingWorkItem); X(MFRegisterLocalByteStreamHandler); X(MFRegisterLocalSchemeHandler); X(MFRemovePeriodicCallback); - X(MFCreateTransformActivate); + X(MFTEnumEx); X(MFTRegisterLocal); X(MFTRegisterLocalByCLSID); X(MFTUnregisterLocal); @@ -4055,6 +4058,8 @@ static void test_MFTRegisterLocal(void) { IClassFactory test_factory = { &test_mft_factory_vtbl }; MFT_REGISTER_TYPE_INFO input_types[1]; + IMFActivate **activate; + UINT32 count, count2; HRESULT hr;
if (!pMFTRegisterLocal) @@ -4071,9 +4076,19 @@ static void test_MFTRegisterLocal(void) hr = pMFTRegisterLocal(&test_factory, &MFT_CATEGORY_OTHER, L"Local MFT name", 0, 1, input_types, 0, NULL); ok(hr == S_OK, "Failed to register MFT, hr %#x.\n", hr);
+ hr = pMFTEnumEx(MFT_CATEGORY_OTHER, MFT_ENUM_FLAG_LOCALMFT, NULL, NULL, &activate, &count); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(count > 0, "Unexpected count %u.\n", count); + CoTaskMemFree(activate); + hr = pMFTUnregisterLocal(&test_factory); ok(hr == S_OK, "Failed to unregister MFT, hr %#x.\n", hr);
+ hr = pMFTEnumEx(MFT_CATEGORY_OTHER, MFT_ENUM_FLAG_LOCALMFT, NULL, NULL, &activate, &count2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(count2 < count, "Unexpected count %u.\n", count2); + CoTaskMemFree(activate); + hr = pMFTUnregisterLocal(&test_factory); ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "Unexpected hr %#x.\n", hr);
diff --git a/include/mfapi.h b/include/mfapi.h index 910b45e68f..4d5ad5ad15 100644 --- a/include/mfapi.h +++ b/include/mfapi.h @@ -422,6 +422,8 @@ HRESULT WINAPI MFGetTimerPeriodicity(DWORD *periodicity); HRESULT WINAPI MFTEnum(GUID category, UINT32 flags, MFT_REGISTER_TYPE_INFO *input_type, MFT_REGISTER_TYPE_INFO *output_type, IMFAttributes *attributes, CLSID **pclsids, UINT32 *pcount); +HRESULT WINAPI MFTEnum2(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INFO *input_type, + const MFT_REGISTER_TYPE_INFO *output_type, IMFAttributes *attributes, IMFActivate ***activate, UINT32 *count); HRESULT WINAPI MFTEnumEx(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INFO *input_type, const MFT_REGISTER_TYPE_INFO *output_type, IMFActivate ***activate, UINT32 *pcount);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/main.c | 31 +++++++++++++++++++++++++++++++ include/mfapi.h | 3 +++ include/mfidl.idl | 2 ++ include/mftransform.idl | 25 +++++++++++++++++++++++++ 4 files changed, 61 insertions(+)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index 45cddd42cc..e63b8fb9c2 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -1475,16 +1475,24 @@ const char *debugstr_attr(const GUID *guid) X(MF_SINK_WRITER_ENCODER_CONFIG), X(MF_TOPOLOGY_NO_MARKIN_MARKOUT), X(MF_SOURCE_READER_ENABLE_TRANSCODE_ONLY_TRANSFORMS), + X(MFT_PREFERRED_ENCODER_PROFILE), X(MF_TOPOLOGY_DYNAMIC_CHANGE_NOT_ALLOWED), X(MF_MT_ALPHA_MODE), X(MF_PMP_SERVER_CONTEXT), + X(MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE), + X(MFT_CODEC_MERIT_Attribute), X(MF_TOPOLOGY_PLAYBACK_MAX_DIMS), X(MF_LOW_LATENCY), X(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS), X(MF_MT_PIXEL_ASPECT_RATIO), X(MF_TOPOLOGY_ENABLE_XVP_FOR_PLAYBACK), + X(MFT_CONNECTED_STREAM_ATTRIBUTE), X(MF_MT_WRAPPED_TYPE), X(MF_MT_AVG_BITRATE), + X(MFT_CONNECTED_TO_HW_STREAM), + X(MF_SA_D3D_AWARE), + X(MFT_TRANSFORM_CLSID_Attribute), + X(MFT_TRANSFORM_CLSID_Attribute), X(MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING), X(MF_SESSION_APPROX_EVENT_OCCURRENCE_TIME), X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_MAX_BUFFERS), @@ -1502,14 +1510,17 @@ const char *debugstr_attr(const GUID *guid) X(MF_MT_ALL_SAMPLES_INDEPENDENT), X(MF_PD_PREFERRED_LANGUAGE), X(MF_PD_PLAYBACK_BOUNDARY_TIME), + X(MF_ACTIVATE_MFT_LOCKED), X(MF_SOURCE_READER_ENABLE_VIDEO_PROCESSING), X(MF_MT_FRAME_SIZE), X(MF_SINK_WRITER_ASYNC_CALLBACK), X(MF_TOPOLOGY_START_TIME_ON_PRESENTATION_SWITCH), + X(MFT_DECODER_EXPOSE_OUTPUT_TYPES_IN_NATIVE_ORDER), X(MF_TOPONODE_WORKQUEUE_MMCSS_PRIORITY), X(MF_MT_FRAME_RATE_RANGE_MAX), X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_PROVIDER_DEVICE_ID), X(MF_TOPOLOGY_STATIC_PLAYBACK_OPTIMIZATIONS), + X(MF_TRANSFORM_CATEGORY_Attribute), X(MF_MT_AUDIO_FLOAT_SAMPLES_PER_SECOND), X(MFSampleExtension_ForwardedDecodeUnits), X(MF_EVENT_SOURCE_TOPOLOGY_CANCELED), @@ -1525,6 +1536,7 @@ const char *debugstr_attr(const GUID *guid) X(MFSampleExtension_Token), X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_CATEGORY), X(MF_MT_AUDIO_VALID_BITS_PER_SAMPLE), + X(MF_TRANSFORM_ASYNC_UNLOCK), X(MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES), X(MF_MT_VIDEO_NO_FRAME_ORDERING), X(MFSampleExtension_3DVideo_SampleFormat), @@ -1536,6 +1548,7 @@ const char *debugstr_attr(const GUID *guid) X(MF_MT_AUDIO_FOLDDOWN_MATRIX), X(MF_MT_AUDIO_WMADRC_PEAKREF), X(MF_MT_AUDIO_WMADRC_PEAKTARGET), + X(MF_TRANSFORM_FLAGS_Attribute), X(MF_PD_SAMI_STYLELIST), X(MF_MT_AUDIO_WMADRC_AVGREF), X(MF_MT_AUDIO_BITS_PER_SAMPLE), @@ -1546,6 +1559,8 @@ const char *debugstr_attr(const GUID *guid) X(MF_SESSION_GLOBAL_TIME), X(MF_SESSION_QUALITY_MANAGER), X(MF_SESSION_CONTENT_PROTECTION_MANAGER), + X(MFT_REMUX_MARK_I_PICTURE_AS_CLEAN_POINT), + X(MFT_REMUX_MARK_I_PICTURE_AS_CLEAN_POINT), X(MF_READWRITE_MMCSS_PRIORITY_AUDIO), X(MF_BYTESTREAM_ORIGIN_NAME), X(MF_BYTESTREAM_CONTENT_TYPE), @@ -1555,6 +1570,7 @@ const char *debugstr_attr(const GUID *guid) X(MF_SD_SAMI_LANGUAGE), X(MF_EVENT_OUTPUT_NODE), X(MF_BYTESTREAM_LAST_MODIFIED_TIME), + X(MFT_ENUM_ADAPTER_LUID), X(MF_MT_FRAME_RATE_RANGE_MIN), X(MF_BYTESTREAM_IFO_FILE_URI), X(MF_EVENT_TOPOLOGY_STATUS), @@ -1565,10 +1581,13 @@ const char *debugstr_attr(const GUID *guid) X(MF_EVENT_SOURCE_CHARACTERISTICS_OLD), X(MF_SESSION_SERVER_CONTEXT), X(MF_MT_VIDEO_3D_FIRST_IS_LEFT), + X(MFT_DECODER_FINAL_VIDEO_RESOLUTION_HINT), X(MF_PD_ADAPTIVE_STREAMING), + X(MFT_PREFERRED_OUTPUTTYPE_Attribute), X(MFSampleExtension_Timestamp), X(MF_TOPONODE_PRIMARYOUTPUT), X(MF_MT_SUBTYPE), + X(MF_TRANSFORM_ASYNC), X(MF_TOPONODE_STREAMID), X(MF_TOPONODE_NOSHUTDOWN_ON_REMOVE), X(MF_SD_MUTUALLY_EXCLUSIVE), @@ -1585,9 +1604,15 @@ const char *debugstr_attr(const GUID *guid) X(MF_EVENT_SOURCE_PROJECTSTART), X(MF_EVENT_SOURCE_ACTUAL_START), X(MF_MT_AUDIO_SAMPLES_PER_BLOCK), + X(MFT_ENUM_HARDWARE_URL_Attribute), X(MF_SOURCE_READER_ASYNC_CALLBACK), + X(MFT_ENCODER_SUPPORTS_CONFIG_EVENT), X(MF_MT_AUDIO_FLAC_MAX_BLOCK_SIZE), + X(MFT_FRIENDLY_NAME_Attribute), X(MF_MT_FIXED_SIZE_SAMPLES), + X(MFT_SUPPORT_3DVIDEO), + X(MFT_SUPPORT_3DVIDEO), + X(MFT_INPUT_TYPES_Attributes), X(MF_EVENT_SCRUBSAMPLE_TIME), X(MF_MT_INTERLACE_MODE), X(MF_MT_VIDEO_RENDERER_EXTENSION_PROFILE), @@ -1601,6 +1626,8 @@ const char *debugstr_attr(const GUID *guid) X(MF_TOPONODE_TRANSFORM_OBJECTID), X(MF_DEVSOURCE_ATTRIBUTE_MEDIA_TYPE), X(MF_EVENT_MFT_INPUT_STREAM_ID), + X(MFT_ENUM_HARDWARE_VENDOR_ID_Attribute), + X(MFT_ENUM_TRANSCODE_ONLY_ATTRIBUTE), X(MF_READWRITE_MMCSS_PRIORITY), X(MF_MT_VIDEO_3D), X(MF_EVENT_START_PRESENTATION_TIME), @@ -1617,6 +1644,8 @@ const char *debugstr_attr(const GUID *guid) X(MF_SOURCE_READER_DISABLE_CAMERA_PLUGINS), X(MF_TOPOLOGY_RESOLUTION_STATUS), X(MF_PD_AUDIO_ISVARIABLEBITRATE), + X(MFT_PROCESS_LOCAL_Attribute), + X(MFT_PROCESS_LOCAL_Attribute), X(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION), X(MF_MT_AUDIO_SAMPLES_PER_SECOND), X(MF_MT_FRAME_RATE), @@ -1635,6 +1664,7 @@ const char *debugstr_attr(const GUID *guid) X(MF_EVENT_MFT_CONTEXT), X(MF_MT_FORWARD_CUSTOM_SEI), X(MF_TOPONODE_CONNECT_METHOD), + X(MFT_OUTPUT_TYPES_Attributes), X(MF_SESSION_REMOTE_SOURCE_MODE), X(MF_MT_DEPTH_VALUE_UNIT), X(MF_MT_AUDIO_NUM_CHANNELS), @@ -1650,6 +1680,7 @@ const char *debugstr_attr(const GUID *guid) X(MF_MT_FORWARD_CUSTOM_NALU), X(MF_TOPONODE_ERROR_MAJORTYPE), X(MF_MT_SECURE), + X(MFT_FIELDOFUSE_UNLOCK_Attribute), X(MF_TOPONODE_ERROR_SUBTYPE), X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE), X(MF_MT_VIDEO_3D_LEFT_IS_BASE), diff --git a/include/mfapi.h b/include/mfapi.h index 4d5ad5ad15..6636057daa 100644 --- a/include/mfapi.h +++ b/include/mfapi.h @@ -274,6 +274,9 @@ DEFINE_GUID(MFT_CATEGORY_AUDIO_ENCODER, 0x91c64bd0, 0xf91e, 0x4d8c, 0x92, 0x76 DEFINE_GUID(MFT_CATEGORY_AUDIO_EFFECT, 0x11064c48, 0x3648, 0x4ed0, 0x93, 0x2e, 0x05, 0xce, 0x8a, 0xc8, 0x11, 0xb7); DEFINE_GUID(MFT_CATEGORY_VIDEO_PROCESSOR, 0x302ea3fc, 0xaa5f, 0x47f9, 0x9f, 0x7a, 0xc2, 0x18, 0x8b, 0xb1, 0x63, 0x02); DEFINE_GUID(MFT_CATEGORY_OTHER, 0x90175d57, 0xb7ea, 0x4901, 0xae, 0xb3, 0x93, 0x3a, 0x87, 0x47, 0x75, 0x6f); +DEFINE_GUID(MFT_ENUM_ADAPTER_LUID, 0x1d39518c, 0xe220, 0x4da8, 0xa0, 0x7f, 0xba, 0x17, 0x25, 0x52, 0xd6, 0xb1); +DEFINE_GUID(MFT_SUPPORT_DYNAMIC_FORMAT_CHANGE, 0x53476a11, 0x3f13, 0x49fb, 0xac, 0x42, 0xee, 0x27, 0x33, 0xc9, 0x67, 0x41); +
DEFINE_GUID(MFMediaType_Audio, 0x73647561, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71); DEFINE_GUID(MFMediaType_Binary, 0x72178c25, 0xe45b, 0x11d5, 0xbc, 0x2a, 0x00, 0xb0, 0xd0, 0xf3, 0xf4, 0xab); diff --git a/include/mfidl.idl b/include/mfidl.idl index 7d3dae0cbb..fa3a2d132a 100644 --- a/include/mfidl.idl +++ b/include/mfidl.idl @@ -834,6 +834,8 @@ cpp_quote(" return attributes->SetUINT64(key, ((UINT64)numerator << 32) | den cpp_quote("}") cpp_quote("#endif")
+cpp_quote("EXTERN_GUID(MF_ACTIVATE_MFT_LOCKED, 0xc1f6093c, 0x7f65, 0x4fbd, 0x9e, 0x39, 0x5f, 0xae, 0xc3, 0xc4, 0xfb, 0xd7);") + cpp_quote("EXTERN_GUID(MF_SD_LANGUAGE, 0x00af2180, 0xbdc2, 0x423c, 0xab, 0xca, 0xf5, 0x03, 0x59, 0x3b, 0xc1, 0x21);") cpp_quote("EXTERN_GUID(MF_SD_MUTUALLY_EXCLUSIVE, 0x023ef79c, 0x388d, 0x487f, 0xac, 0x17, 0x69, 0x6c, 0xd6, 0xe3, 0xc6, 0xf5);") cpp_quote("EXTERN_GUID(MF_SD_PROTECTED, 0x00af2181, 0xbdc2, 0x423c, 0xab, 0xca, 0xf5, 0x03, 0x59, 0x3b, 0xc1, 0x21);") diff --git a/include/mftransform.idl b/include/mftransform.idl index 5c4860c367..8cc0ffbc50 100644 --- a/include/mftransform.idl +++ b/include/mftransform.idl @@ -123,3 +123,28 @@ interface IMFTransform : IUnknown }
cpp_quote("HRESULT WINAPI MFCreateTransformActivate(IMFActivate **activate);") + +cpp_quote("EXTERN_GUID(MF_SA_D3D_AWARE, 0xeaa35c29, 0x775e, 0x488e, 0x9b, 0x61, 0xb3, 0x28, 0x3e, 0x49, 0x58, 0x3b);") +cpp_quote("EXTERN_GUID(MF_TRANSFORM_ASYNC, 0xf81a699a, 0x649a, 0x497d, 0x8c, 0x73, 0x29, 0xf8, 0xfe, 0xd6, 0xad, 0x7a);") +cpp_quote("EXTERN_GUID(MF_TRANSFORM_ASYNC_UNLOCK, 0xe5666d6b, 0x3422, 0x4eb6, 0xa4, 0x21, 0xda, 0x7d, 0xb1, 0xf8, 0xe2, 0x07);") +cpp_quote("EXTERN_GUID(MF_TRANSFORM_CATEGORY_Attribute, 0xceabba49, 0x506d, 0x4757, 0xa6, 0xff, 0x66, 0xc1, 0x84, 0x98, 0x7e, 0x4e);") +cpp_quote("EXTERN_GUID(MF_TRANSFORM_FLAGS_Attribute, 0x9359bb7e, 0x6275, 0x46c4, 0xa0, 0x25, 0x1c, 0x01, 0xe4, 0x5f, 0x1a, 0x86);") +cpp_quote("EXTERN_GUID(MFT_CODEC_MERIT_Attribute, 0x88a7cb15, 0x7b07, 0x4a34, 0x91, 0x28, 0xe6, 0x4c, 0x67, 0x03, 0xc4, 0xd3);") +cpp_quote("EXTERN_GUID(MFT_CONNECTED_STREAM_ATTRIBUTE, 0x71eeb820, 0xa59f, 0x4de2, 0xbc, 0xec, 0x38, 0xdb, 0x1d, 0xd6, 0x11, 0xa4);") +cpp_quote("EXTERN_GUID(MFT_CONNECTED_TO_HW_STREAM, 0x34e6e728, 0x06d6, 0x4491, 0xa5, 0x53, 0x47, 0x95, 0x65, 0x0d, 0xb9, 0x12);") +cpp_quote("EXTERN_GUID(MFT_DECODER_EXPOSE_OUTPUT_TYPES_IN_NATIVE_ORDER, 0xef80833f, 0xf8fa, 0x44d9, 0x80, 0xd8, 0x41, 0xed, 0x62, 0x32, 0x67, 0x0c);") +cpp_quote("EXTERN_GUID(MFT_DECODER_FINAL_VIDEO_RESOLUTION_HINT, 0xdc2f8496, 0x15c4, 0x407a, 0xb6, 0xf0, 0x1b, 0x66, 0xab, 0x5f, 0xbf, 0x53);") +cpp_quote("EXTERN_GUID(MFT_ENCODER_SUPPORTS_CONFIG_EVENT, 0x86a355ae, 0x3a77, 0x4ec4, 0x9f, 0x31, 0x01, 0x14, 0x9a, 0x4e, 0x92, 0xde);") +cpp_quote("EXTERN_GUID(MFT_ENUM_HARDWARE_URL_Attribute, 0x2fb866ac, 0xb078, 0x4942, 0xab, 0x6c, 0x00, 0x3d, 0x05, 0xcd, 0xa6, 0x74);") +cpp_quote("EXTERN_GUID(MFT_ENUM_HARDWARE_VENDOR_ID_Attribute, 0x3aecb0cc, 0x035b, 0x4bcc, 0x81, 0x85, 0x2b, 0x8d, 0x55, 0x1e, 0xf3, 0xaf);") +cpp_quote("EXTERN_GUID(MFT_ENUM_TRANSCODE_ONLY_ATTRIBUTE, 0x111ea8cd, 0xb62a, 0x4bdb, 0x89, 0xf6, 0x67, 0xff, 0xcd, 0xc2, 0x45, 0x8b);") +cpp_quote("EXTERN_GUID(MFT_FIELDOFUSE_UNLOCK_Attribute, 0x8ec2e9fd, 0x9148, 0x410d, 0x83, 0x1e, 0x70, 0x24, 0x39, 0x46, 0x1a, 0x8e);") +cpp_quote("EXTERN_GUID(MFT_FRIENDLY_NAME_Attribute, 0x314ffbae, 0x5b41, 0x4c95, 0x9c, 0x19, 0x4e, 0x7d, 0x58, 0x6f, 0xac, 0xe3);") +cpp_quote("EXTERN_GUID(MFT_INPUT_TYPES_Attributes, 0x4276c9b1, 0x759d, 0x4bf3, 0x9c, 0xd0, 0x0d, 0x72, 0x3d, 0x13, 0x8f, 0x96);") +cpp_quote("EXTERN_GUID(MFT_OUTPUT_TYPES_Attributes, 0x8eae8cf3, 0xa44f, 0x4306, 0xba, 0x5c, 0xbf, 0x5d, 0xda, 0x24, 0x28, 0x18);") +cpp_quote("EXTERN_GUID(MFT_PREFERRED_ENCODER_PROFILE, 0x53004909, 0x1ef5, 0x46d7, 0xa1, 0x8e, 0x5a, 0x75, 0xf8, 0xb5, 0x90, 0x5f);") +cpp_quote("EXTERN_GUID(MFT_PREFERRED_OUTPUTTYPE_Attribute, 0x7e700499, 0x396a, 0x49ee, 0xb1, 0xb4, 0xf6, 0x28, 0x02, 0x1e, 0x8c, 0x9d);") +cpp_quote("EXTERN_GUID(MFT_PROCESS_LOCAL_Attribute, 0x543186e4, 0x4649, 0x4e65, 0xb5, 0x88, 0x4a, 0xa3, 0x52, 0xaf, 0xf3, 0x79);") +cpp_quote("EXTERN_GUID(MFT_REMUX_MARK_I_PICTURE_AS_CLEAN_POINT, 0x364e8f85, 0x3f2e, 0x436c, 0xb2, 0xa2, 0x44, 0x40, 0xa0, 0x12, 0xa9, 0xe8);") +cpp_quote("EXTERN_GUID(MFT_SUPPORT_3DVIDEO, 0x093f81b1, 0x4f2e, 0x4631, 0x81, 0x68, 0x79, 0x34, 0x03, 0x2a, 0x01, 0xd3);") +cpp_quote("EXTERN_GUID(MFT_TRANSFORM_CLSID_Attribute, 0x6821c42b, 0x65a4, 0x4e82, 0x99, 0xbc, 0x9a, 0x88, 0x20, 0x5e, 0xcd, 0x0c);")
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/main.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index e63b8fb9c2..d15bf00337 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -1265,7 +1265,27 @@ static HRESULT mft_enum(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INF { (*activate)[obj_count] = mft_activate;
- /* FIXME: set some attributes */ + if (mft->flags & MFT_ENUM_FLAG_LOCALMFT) + { + IMFActivate_SetUINT32(mft_activate, &MFT_PROCESS_LOCAL_Attribute, 1); + } + else + { + if (mft->name) + IMFActivate_SetString(mft_activate, &MFT_FRIENDLY_NAME_Attribute, mft->name); + if (mft->input_types) + IMFActivate_SetBlob(mft_activate, &MFT_INPUT_TYPES_Attributes, (const UINT8 *)mft->input_types, + sizeof(*mft->input_types) * mft->input_types_count); + if (mft->output_types) + IMFActivate_SetBlob(mft_activate, &MFT_OUTPUT_TYPES_Attributes, (const UINT8 *)mft->output_types, + sizeof(*mft->output_types) * mft->output_types_count); + } + + if (!mft->factory) + IMFActivate_SetGUID(mft_activate, &MFT_TRANSFORM_CLSID_Attribute, &mft->clsid); + + IMFActivate_SetUINT32(mft_activate, &MF_TRANSFORM_FLAGS_Attribute, mft->flags); + IMFActivate_SetGUID(mft_activate, &MF_TRANSFORM_CATEGORY_Attribute, &mft->category);
obj_count++; }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/main.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index d15bf00337..a1314f6eb3 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -97,6 +97,7 @@ struct mft_registration UINT32 input_types_count; MFT_REGISTER_TYPE_INFO *output_types; UINT32 output_types_count; + BOOL local; };
static CRITICAL_SECTION local_mfts_section = { NULL, -1, 0, 0, 0, 0 }; @@ -818,7 +819,10 @@ static HRESULT mft_register_local(IClassFactory *factory, REFCLSID clsid, REFGUI if (clsid) mft->clsid = *clsid; mft->category = *category; - mft->flags = flags | MFT_ENUM_FLAG_LOCALMFT; + if (!(flags & (MFT_ENUM_FLAG_SYNCMFT | MFT_ENUM_FLAG_ASYNCMFT | MFT_ENUM_FLAG_HARDWARE))) + flags |= MFT_ENUM_FLAG_SYNCMFT; + mft->flags = flags; + mft->local = TRUE; if (FAILED(hr = heap_strdupW(name, &mft->name))) goto failed;
@@ -1198,6 +1202,7 @@ static HRESULT mft_enum(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INF if (mft->factory) IClassFactory_AddRef(mft->factory); mft->flags = local->flags; + mft->local = local->local;
list_add_tail(&mfts, &mft->entry); } @@ -1213,7 +1218,7 @@ static HRESULT mft_enum(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INF /* Local registrations. */ LIST_FOR_EACH_ENTRY_SAFE(mft, mft2, &mfts, struct mft_registration, entry) { - if (mft->flags & MFT_ENUM_FLAG_LOCALMFT) + if (mft->local) { list_remove(&mft->entry); list_add_tail(&mfts_sorted, &mft->entry); @@ -1239,7 +1244,7 @@ static HRESULT mft_enum(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INF list_add_tail(&mfts_sorted, &mft->entry); }
- result = &mfts; + result = &mfts_sorted; }
IMFPluginControl_Release(plugin_control); @@ -1265,7 +1270,7 @@ static HRESULT mft_enum(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_INF { (*activate)[obj_count] = mft_activate;
- if (mft->flags & MFT_ENUM_FLAG_LOCALMFT) + if (mft->local) { IMFActivate_SetUINT32(mft_activate, &MFT_PROCESS_LOCAL_Attribute, 1); }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/main.c | 59 ++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 5 deletions(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index a1314f6eb3..61272beccb 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -109,6 +109,7 @@ struct transform_activate struct attributes attributes; IMFActivate IMFActivate_iface; IClassFactory *factory; + IMFTransform *transform; };
struct system_clock @@ -198,6 +199,8 @@ static ULONG WINAPI transform_activate_Release(IMFActivate *iface) clear_attributes_object(&activate->attributes); if (activate->factory) IClassFactory_Release(activate->factory); + if (activate->transform) + IMFTransform_Release(activate->transform); heap_free(activate); }
@@ -482,21 +485,67 @@ static HRESULT WINAPI transform_activate_CopyAllItems(IMFActivate *iface, IMFAtt
static HRESULT WINAPI transform_activate_ActivateObject(IMFActivate *iface, REFIID riid, void **obj) { - FIXME("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); + struct transform_activate *activate = impl_from_IMFActivate(iface); + CLSID clsid; + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); + + EnterCriticalSection(&activate->attributes.cs); + + if (!activate->transform) + { + if (activate->factory) + { + if (FAILED(hr = IClassFactory_CreateInstance(activate->factory, NULL, &IID_IMFTransform, + (void **)&activate->transform))) + { + hr = MF_E_INVALIDREQUEST; + } + } + else + { + if (SUCCEEDED(hr = attributes_GetGUID(&activate->attributes, &MFT_TRANSFORM_CLSID_Attribute, &clsid))) + { + if (FAILED(hr = CoCreateInstance(&clsid, NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, + (void **)&activate->transform))) + { + hr = MF_E_INVALIDREQUEST; + } + } + } + } + + if (activate->transform) + hr = IMFTransform_QueryInterface(activate->transform, riid, obj); + + LeaveCriticalSection(&activate->attributes.cs); + + return hr; }
static HRESULT WINAPI transform_activate_ShutdownObject(IMFActivate *iface) { - FIXME("%p.\n", iface); + struct transform_activate *activate = impl_from_IMFActivate(iface);
- return E_NOTIMPL; + TRACE("%p.\n", iface); + + EnterCriticalSection(&activate->attributes.cs); + + if (activate->transform) + { + IMFTransform_Release(activate->transform); + activate->transform; + } + + LeaveCriticalSection(&activate->attributes.cs); + + return S_OK; }
static HRESULT WINAPI transform_activate_DetachObject(IMFActivate *iface) { - FIXME("%p.\n", iface); + TRACE("%p.\n", iface);
return E_NOTIMPL; }
Nikolay Sivov nsivov@codeweavers.com writes:
static HRESULT WINAPI transform_activate_ShutdownObject(IMFActivate *iface) {
- FIXME("%p.\n", iface);
- struct transform_activate *activate = impl_from_IMFActivate(iface);
- return E_NOTIMPL;
- TRACE("%p.\n", iface);
- EnterCriticalSection(&activate->attributes.cs);
- if (activate->transform)
- {
IMFTransform_Release(activate->transform);
activate->transform;
Did you mean to set it to NULL here?