Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/main.c | 1 + dlls/mfplat/mediatype.c | 72 ++++++++++++++++++++++++++++++++++++++ dlls/mfplat/mfplat.spec | 4 +-- dlls/mfplat/tests/mfplat.c | 57 ++++++++++++++++++++++++++++++ include/mfapi.h | 3 ++ 5 files changed, 135 insertions(+), 2 deletions(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index 30c3073f09..dd89f4c91a 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -559,6 +559,7 @@ static const char *debugstr_attr(const GUID *guid) X(MF_SOURCE_READER_ENABLE_TRANSCODE_ONLY_TRANSFORMS), X(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS), X(MF_MT_PIXEL_ASPECT_RATIO), + X(MF_MT_WRAPPED_TYPE), X(MF_MT_AVG_BITRATE), X(MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING), X(MF_PD_PMPHOST_CONTEXT), diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index a2e3a96902..e64dd3da63 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -1515,3 +1515,75 @@ BOOL WINAPI MFCompareFullToPartialMediaType(IMFMediaType *full_type, IMFMediaTyp
return result; } + +/*********************************************************************** + * MFWrapMediaType (mfplat.@) + */ +HRESULT WINAPI MFWrapMediaType(IMFMediaType *original, REFGUID major, REFGUID subtype, IMFMediaType **ret) +{ + IMFMediaType *mediatype; + UINT8 *buffer; + UINT32 size; + HRESULT hr; + + TRACE("%p, %s, %s, %p.\n", original, debugstr_guid(major), debugstr_guid(subtype), ret); + + if (FAILED(hr = MFGetAttributesAsBlobSize((IMFAttributes *)original, &size))) + return hr; + + if (!(buffer = heap_alloc(size))) + return E_OUTOFMEMORY; + + if (FAILED(hr = MFGetAttributesAsBlob((IMFAttributes *)original, buffer, size))) + goto failed; + + if (FAILED(hr = MFCreateMediaType(&mediatype))) + goto failed; + + if (FAILED(hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, major))) + goto failed; + + if (FAILED(hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, subtype))) + goto failed; + + if (FAILED(hr = IMFMediaType_SetBlob(mediatype, &MF_MT_WRAPPED_TYPE, buffer, size))) + goto failed; + + *ret = mediatype; + +failed: + heap_free(buffer); + + return hr; +} + +/*********************************************************************** + * MFUnwrapMediaType (mfplat.@) + */ +HRESULT WINAPI MFUnwrapMediaType(IMFMediaType *wrapper, IMFMediaType **ret) +{ + IMFMediaType *mediatype; + UINT8 *buffer; + UINT32 size; + HRESULT hr; + + TRACE("%p, %p.\n", wrapper, ret); + + if (FAILED(hr = MFCreateMediaType(&mediatype))) + return hr; + + if (FAILED(hr = IMFMediaType_GetAllocatedBlob(wrapper, &MF_MT_WRAPPED_TYPE, &buffer, &size))) + { + IMFMediaType_Release(mediatype); + return hr; + } + + hr = MFInitAttributesFromBlob((IMFAttributes *)mediatype, buffer, size); + CoTaskMemFree(buffer); + if (FAILED(hr)) + return hr; + + *ret = mediatype; + + return S_OK; +} diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec index 4272a206e6..79f25f53d5 100644 --- a/dlls/mfplat/mfplat.spec +++ b/dlls/mfplat/mfplat.spec @@ -152,9 +152,9 @@ @ stub MFUnblockThread @ stdcall MFUnlockPlatform() @ stdcall MFUnlockWorkQueue(long) -@ stub MFUnwrapMediaType +@ stdcall MFUnwrapMediaType(ptr ptr) @ stub MFValidateMediaTypeSize -@ stub MFWrapMediaType +@ stdcall MFWrapMediaType(ptr ptr ptr ptr) @ stub MFllMulDiv @ stub PropVariantFromStream @ stub PropVariantToStream diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 85fc176046..d53251c318 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -2616,6 +2616,62 @@ static void test_attributes_serialization(void) IMFAttributes_Release(dest); }
+static void test_wrapped_media_type(void) +{ + IMFMediaType *mediatype, *mediatype2; + UINT32 count, type; + HRESULT hr; + GUID guid; + + hr = MFCreateMediaType(&mediatype); + ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr); + + hr = MFUnwrapMediaType(mediatype, &mediatype2); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr); + + hr = IMFMediaType_SetUINT32(mediatype, &GUID_NULL, 1); + ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); + hr = IMFMediaType_SetUINT32(mediatype, &DUMMY_GUID1, 2); + ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr); + + hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "Failed to set GUID value, hr %#x.\n", hr); + + hr = MFWrapMediaType(mediatype, &MFMediaType_Audio, &IID_IUnknown, &mediatype2); + ok(hr == S_OK, "Failed to create wrapped media type, hr %#x.\n", hr); + + hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_MAJOR_TYPE, &guid); + ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr); + ok(IsEqualGUID(&guid, &MFMediaType_Audio), "Unexpected major type.\n"); + + hr = IMFMediaType_GetGUID(mediatype2, &MF_MT_SUBTYPE, &guid); + ok(hr == S_OK, "Failed to get subtype, hr %#x.\n", hr); + ok(IsEqualGUID(&guid, &IID_IUnknown), "Unexpected major type.\n"); + + hr = IMFMediaType_GetCount(mediatype2, &count); + ok(hr == S_OK, "Failed to get item count, hr %#x.\n", hr); + ok(count == 3, "Unexpected count %u.\n", count); + + hr = IMFMediaType_GetItemType(mediatype2, &MF_MT_WRAPPED_TYPE, &type); + ok(hr == S_OK, "Failed to get item type, hr %#x.\n", hr); + ok(type == MF_ATTRIBUTE_BLOB, "Unexpected item type.\n"); + + IMFMediaType_Release(mediatype); + + hr = MFUnwrapMediaType(mediatype2, &mediatype); + ok(hr == S_OK, "Failed to unwrap, hr %#x.\n", hr); + + hr = IMFMediaType_GetGUID(mediatype, &MF_MT_MAJOR_TYPE, &guid); + ok(hr == S_OK, "Failed to get major type, hr %#x.\n", hr); + ok(IsEqualGUID(&guid, &MFMediaType_Video), "Unexpected major type.\n"); + + hr = IMFMediaType_GetGUID(mediatype, &MF_MT_SUBTYPE, &guid); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#x.\n", hr); + + IMFMediaType_Release(mediatype); + IMFMediaType_Release(mediatype2); +} + START_TEST(mfplat) { CoInitialize(NULL); @@ -2648,6 +2704,7 @@ START_TEST(mfplat) test_MFCalculateImageSize(); test_MFCompareFullToPartialMediaType(); test_attributes_serialization(); + test_wrapped_media_type();
CoUninitialize(); } diff --git a/include/mfapi.h b/include/mfapi.h index b082f9c2dd..2d794e49eb 100644 --- a/include/mfapi.h +++ b/include/mfapi.h @@ -105,6 +105,7 @@ DEFINE_GUID(MF_MT_ALL_SAMPLES_INDEPENDENT, 0xc9173739, 0x5e56, 0x461c, 0xb7, 0x1 DEFINE_GUID(MF_MT_USER_DATA, 0xb6bc765f, 0x4c3b, 0x40a4, 0xbd, 0x51, 0x25, 0x35, 0xb6, 0x6f, 0xe0, 0x9d); DEFINE_GUID(MF_MT_FRAME_RATE_RANGE_MIN, 0xd2e7558c, 0xdc1f, 0x403f, 0x9a, 0x72, 0xd2, 0x8b, 0xb1, 0xeb, 0x3b, 0x5e); DEFINE_GUID(MF_MT_FRAME_RATE_RANGE_MAX, 0xe3371d41, 0xb4cf, 0x4a05, 0xbd, 0x4e, 0x20, 0xb8, 0x8b, 0xb2, 0xc4, 0xd6); +DEFINE_GUID(MF_MT_WRAPPED_TYPE, 0x4d3f7b23, 0xd02f, 0x4e6c, 0x9b, 0xee, 0xe4, 0xbf, 0x2c, 0x6c, 0x69, 0x5d);
DEFINE_GUID(MFT_CATEGORY_VIDEO_DECODER, 0xd6c02d4b, 0x6833, 0x45b4, 0x97, 0x1a, 0x05, 0xa4, 0xb0, 0x4b, 0xab, 0x91); DEFINE_GUID(MFT_CATEGORY_VIDEO_ENCODER, 0xf79eac7d, 0xe545, 0x4387, 0xbd, 0xee, 0xd6, 0x47, 0xd7, 0xbd, 0xe4, 0x2a); @@ -236,6 +237,8 @@ HRESULT WINAPI MFUnlockWorkQueue(DWORD queue); HRESULT WINAPI MFTUnregister(CLSID clsid); HRESULT WINAPI MFTUnregisterLocal(IClassFactory *factory); HRESULT WINAPI MFGetPluginControl(IMFPluginControl**); +HRESULT WINAPI MFWrapMediaType(IMFMediaType *original, REFGUID major, REFGUID subtype, IMFMediaType **wrapped); +HRESULT WINAPI MFUnwrapMediaType(IMFMediaType *wrapped, IMFMediaType **original);
#if defined(__cplusplus) }