IMFMediaType_(Get|Free)Representation is called by Samurai Maiden, MFInitAMMediaTypeFromMFMediaType could be useful to simplify DMO / MFT transforms implementations.
-- v2: mfplat: Implement IMFMediaType_(Get|Free)Representation. mfplat: Implement MFCreateAMMediaTypeFromMFMediaType. mfplat: Implement MFInitAMMediaTypeFromMFMediaType. mfplat: Use bits per pixel in uncompressed formats metadata. mfplat: Only convert MEDIASUBTYPE for the formats that need it. mfplat/tests: Add IMFMediaType_GetRepresentation tests. mfplat/tests: Add tests for MFCreateAMMediaTypeFromMFMediaType. mfplat/tests: Add tests for MFInitAMMediaTypeFromMFMediaType. mfplat: Add MFInitAMMediaTypeFromMFMediaType stub. mfplat: Add MFCreateAMMediaTypeFromMFMediaType stub.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/mediatype.c | 9 +++++++++ dlls/mfplat/mfplat.spec | 2 +- include/mfapi.h | 1 + 3 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index 0b4a6fa4eaf..2b699435d25 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -3121,6 +3121,15 @@ static void media_type_get_ratio(IMFMediaType *media_type, const GUID *attr, DWO } }
+/*********************************************************************** + * MFCreateAMMediaTypeFromMFMediaType (mfplat.@) + */ +HRESULT WINAPI MFCreateAMMediaTypeFromMFMediaType(IMFMediaType *media_type, GUID format, AM_MEDIA_TYPE **am_type) +{ + FIXME("%p, %s, %p stub!\n", media_type, debugstr_mf_guid(&format), am_type); + return E_NOTIMPL; +} + /*********************************************************************** * MFCreateMFVideoFormatFromMFMediaType (mfplat.@) */ diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec index 2f18d6380d6..bbe938b2b2c 100644 --- a/dlls/mfplat/mfplat.spec +++ b/dlls/mfplat/mfplat.spec @@ -39,7 +39,7 @@ @ stub MFConvertToFP16Array @ stdcall MFCopyImage(ptr long ptr long long long) @ stdcall MFCreate2DMediaBuffer(long long long long ptr) -@ stub MFCreateAMMediaTypeFromMFMediaType +@ stdcall MFCreateAMMediaTypeFromMFMediaType(ptr int128 ptr) @ stdcall MFCreateAlignedMemoryBuffer(long long ptr) @ stdcall MFCreateAsyncResult(ptr ptr ptr ptr) rtworkq.RtwqCreateAsyncResult @ stdcall MFCreateAttributes(ptr long) diff --git a/include/mfapi.h b/include/mfapi.h index 105b093893f..bdf68adf45d 100644 --- a/include/mfapi.h +++ b/include/mfapi.h @@ -545,6 +545,7 @@ HRESULT WINAPI MFCreateMediaBufferFromMediaType(IMFMediaType *media_type, LONGLO HRESULT WINAPI MFCreateMediaEvent(MediaEventType type, REFGUID extended_type, HRESULT status, const PROPVARIANT *value, IMFMediaEvent **event); HRESULT WINAPI MFCreateMediaType(IMFMediaType **type); +HRESULT WINAPI MFCreateAMMediaTypeFromMFMediaType(IMFMediaType *media_type, GUID format_type, AM_MEDIA_TYPE **am_type); HRESULT WINAPI MFCreateMFVideoFormatFromMFMediaType(IMFMediaType *media_type, MFVIDEOFORMAT **video_format, UINT32 *size); HRESULT WINAPI MFCreateSample(IMFSample **sample); HRESULT WINAPI MFCreateTempFile(MF_FILE_ACCESSMODE accessmode, MF_FILE_OPENMODE openmode, MF_FILE_FLAGS flags,
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/mediatype.c | 9 +++++++++ dlls/mfplat/mfplat.spec | 2 +- include/mfapi.h | 1 + 3 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index 2b699435d25..437e5aba869 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -3679,6 +3679,15 @@ HRESULT WINAPI MFInitMediaTypeFromVideoInfoHeader(IMFMediaType *media_type, cons return hr; }
+/*********************************************************************** + * MFInitAMMediaTypeFromMFMediaType (mfplat.@) + */ +HRESULT WINAPI MFInitAMMediaTypeFromMFMediaType(IMFMediaType *media_type, GUID format, AM_MEDIA_TYPE *am_type) +{ + FIXME("%p, %s, %p\n", media_type, debugstr_guid(&format), am_type); + return E_NOTIMPL; +} + /*********************************************************************** * MFInitMediaTypeFromAMMediaType (mfplat.@) */ diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec index bbe938b2b2c..d7f75351960 100644 --- a/dlls/mfplat/mfplat.spec +++ b/dlls/mfplat/mfplat.spec @@ -117,7 +117,7 @@ @ stdcall MFGetWorkQueueMMCSSPriority(long ptr) rtworkq.RtwqGetWorkQueueMMCSSPriority @ stdcall MFHeapAlloc(long long str long long) @ stdcall MFHeapFree(ptr) -@ stub MFInitAMMediaTypeFromMFMediaType +@ stdcall MFInitAMMediaTypeFromMFMediaType(ptr int128 ptr) @ stdcall MFInitAttributesFromBlob(ptr ptr long) @ stdcall MFInitMediaTypeFromAMMediaType(ptr ptr) @ stub MFInitMediaTypeFromMFVideoFormat diff --git a/include/mfapi.h b/include/mfapi.h index bdf68adf45d..ef5bec16369 100644 --- a/include/mfapi.h +++ b/include/mfapi.h @@ -589,6 +589,7 @@ HRESULT WINAPI MFTGetInfo(CLSID clsid, WCHAR **name, MFT_REGISTER_TYPE_INFO **in MFT_REGISTER_TYPE_INFO **output_types, UINT32 *output_types_count, IMFAttributes **attributes); BOOL WINAPI MFIsFormatYUV(DWORD format); HRESULT WINAPI MFInitAttributesFromBlob(IMFAttributes *attributes, const UINT8 *buffer, UINT size); +HRESULT WINAPI MFInitAMMediaTypeFromMFMediaType(IMFMediaType *media_type, GUID format, AM_MEDIA_TYPE *am_type); HRESULT WINAPI MFInitMediaTypeFromAMMediaType(IMFMediaType *mediatype, const AM_MEDIA_TYPE *am_type); HRESULT WINAPI MFInitMediaTypeFromVideoInfoHeader(IMFMediaType *media_type, const VIDEOINFOHEADER *vih, UINT32 size, const GUID *subtype);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/tests/mfplat.c | 501 +++++++++++++++++++++++++++++++++++++ 1 file changed, 501 insertions(+)
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 4fcf5f19558..bb01686fb9c 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -57,6 +57,7 @@ #define EXTERN_GUID DEFINE_GUID #include "mfd3d12.h" #include "wmcodecdsp.h" +#include "dvdmedia.h"
DEFINE_GUID(DUMMY_CLSID, 0x12345678,0x1234,0x1234,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19); DEFINE_GUID(DUMMY_GUID1, 0x12345678,0x1234,0x1234,0x21,0x21,0x21,0x21,0x21,0x21,0x21,0x21); @@ -7026,6 +7027,505 @@ static void test_MFCreateMFVideoFormatFromMFMediaType(void) IMFMediaType_Release(media_type); }
+static void test_MFInitAMMediaTypeFromMFMediaType(void) +{ + static const MFVideoArea aperture = {.OffsetX = {.fract = 1, .value = 2}, .OffsetY = {.fract = 3, .value = 4}, .Area={56,78}}; + static const BYTE dummy_user_data[] = {0x01,0x02,0x03}; + + WAVEFORMATEXTENSIBLE *wave_format_ext; + VIDEOINFOHEADER *video_info; + WAVEFORMATEX *wave_format; + IMFMediaType *media_type; + AM_MEDIA_TYPE am_type; + HRESULT hr; + + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr); + + /* test basic media type attributes mapping and valid formats */ + + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + todo_wine ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + todo_wine ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + todo_wine ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, FORMAT_VideoInfo, &am_type); + todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (hr != S_OK) goto skip_tests; + ok(IsEqualGUID(&am_type.majortype, &MFMediaType_Audio), "got %s.\n", debugstr_guid(&am_type.majortype)); + ok(IsEqualGUID(&am_type.subtype, &MFAudioFormat_PCM), "got %s.\n", debugstr_guid(&am_type.subtype)); + ok(IsEqualGUID(&am_type.formattype, &FORMAT_WaveFormatEx), "got %s.\n", debugstr_guid(&am_type.formattype)); + ok(am_type.cbFormat == sizeof(WAVEFORMATEX), "got %lu\n", am_type.cbFormat); + CoTaskMemFree(am_type.pbFormat); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, AM_MEDIA_TYPE_REPRESENTATION, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&am_type.majortype, &MFMediaType_Audio), "got %s.\n", debugstr_guid(&am_type.majortype)); + ok(IsEqualGUID(&am_type.subtype, &MFAudioFormat_PCM), "got %s.\n", debugstr_guid(&am_type.subtype)); + ok(IsEqualGUID(&am_type.formattype, &GUID_NULL), "got %s.\n", debugstr_guid(&am_type.formattype)); + ok(am_type.cbFormat == 0, "got %lu\n", am_type.cbFormat); + CoTaskMemFree(am_type.pbFormat); + IMFMediaType_DeleteAllItems(media_type); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, FORMAT_WaveFormatEx, &am_type); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&am_type.majortype, &MFMediaType_Video), "got %s.\n", debugstr_guid(&am_type.majortype)); + ok(IsEqualGUID(&am_type.subtype, &MEDIASUBTYPE_RGB32), "got %s.\n", debugstr_guid(&am_type.subtype)); + ok(IsEqualGUID(&am_type.formattype, &FORMAT_VideoInfo), "got %s.\n", debugstr_guid(&am_type.formattype)); + ok(am_type.cbFormat == sizeof(VIDEOINFOHEADER), "got %lu\n", am_type.cbFormat); + CoTaskMemFree(am_type.pbFormat); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, AM_MEDIA_TYPE_REPRESENTATION, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&am_type.majortype, &MFMediaType_Video), "got %s.\n", debugstr_guid(&am_type.majortype)); + ok(IsEqualGUID(&am_type.subtype, &MFVideoFormat_RGB32), "got %s.\n", debugstr_guid(&am_type.subtype)); + ok(IsEqualGUID(&am_type.formattype, &GUID_NULL), "got %s.\n", debugstr_guid(&am_type.formattype)); + ok(am_type.cbFormat == 0, "got %lu\n", am_type.cbFormat); + CoTaskMemFree(am_type.pbFormat); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, FORMAT_VideoInfo, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&am_type.majortype, &MFMediaType_Video), "got %s.\n", debugstr_guid(&am_type.majortype)); + ok(IsEqualGUID(&am_type.subtype, &MEDIASUBTYPE_RGB32), "got %s.\n", debugstr_guid(&am_type.subtype)); + ok(IsEqualGUID(&am_type.formattype, &FORMAT_VideoInfo), "got %s.\n", debugstr_guid(&am_type.formattype)); + ok(am_type.cbFormat == sizeof(VIDEOINFOHEADER), "got %lu\n", am_type.cbFormat); + CoTaskMemFree(am_type.pbFormat); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, FORMAT_VideoInfo2, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&am_type.majortype, &MFMediaType_Video), "got %s.\n", debugstr_guid(&am_type.majortype)); + ok(IsEqualGUID(&am_type.subtype, &MEDIASUBTYPE_RGB32), "got %s.\n", debugstr_guid(&am_type.subtype)); + ok(IsEqualGUID(&am_type.formattype, &FORMAT_VideoInfo2), "got %s.\n", debugstr_guid(&am_type.formattype)); + ok(am_type.cbFormat == sizeof(VIDEOINFOHEADER2), "got %lu\n", am_type.cbFormat); + CoTaskMemFree(am_type.pbFormat); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, FORMAT_MFVideoFormat, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&am_type.majortype, &MFMediaType_Video), "got %s.\n", debugstr_guid(&am_type.majortype)); + ok(IsEqualGUID(&am_type.subtype, &MFVideoFormat_RGB32), "got %s.\n", debugstr_guid(&am_type.subtype)); + ok(IsEqualGUID(&am_type.formattype, &FORMAT_MFVideoFormat), "got %s.\n", debugstr_guid(&am_type.formattype)); + ok(am_type.cbFormat == sizeof(MFVIDEOFORMAT), "got %lu\n", am_type.cbFormat); + CoTaskMemFree(am_type.pbFormat); + + + /* test WAVEFORMATEX mapping */ + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetBlob(media_type, &MF_MT_USER_DATA, dummy_user_data, sizeof(dummy_user_data)); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(am_type.cbFormat == sizeof(WAVEFORMATEX) + sizeof(dummy_user_data), "got %lu\n", am_type.cbFormat); + wave_format = (WAVEFORMATEX *)am_type.pbFormat; + ok(wave_format->wFormatTag == WAVE_FORMAT_PCM, "got %u\n", wave_format->wFormatTag); + ok(wave_format->nChannels == 0, "got %u\n", wave_format->nChannels); + ok(wave_format->nSamplesPerSec == 0, "got %lu\n", wave_format->nSamplesPerSec); + ok(wave_format->nAvgBytesPerSec == 0, "got %lu\n", wave_format->nAvgBytesPerSec); + ok(wave_format->nBlockAlign == 0, "got %u\n", wave_format->nBlockAlign); + ok(wave_format->wBitsPerSample == 0, "got %u\n", wave_format->wBitsPerSample); + ok(wave_format->cbSize == sizeof(dummy_user_data), "got %u\n", wave_format->cbSize); + ok(!memcmp(wave_format + 1, dummy_user_data, sizeof(dummy_user_data)), "got unexpected data\n"); + CoTaskMemFree(am_type.pbFormat); + IMFMediaType_DeleteAllItems(media_type); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_NUM_CHANNELS, 2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(am_type.cbFormat == sizeof(WAVEFORMATEX), "got %lu\n", am_type.cbFormat); + wave_format = (WAVEFORMATEX *)am_type.pbFormat; + ok(wave_format->wFormatTag == WAVE_FORMAT_PCM, "got %u\n", wave_format->wFormatTag); + ok(wave_format->nChannels == 2, "got %u\n", wave_format->nChannels); + ok(wave_format->cbSize == 0, "got %u\n", wave_format->cbSize); + CoTaskMemFree(am_type.pbFormat); + IMFMediaType_DeleteAllItems(media_type); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_NUM_CHANNELS, 2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BITS_PER_SAMPLE, 16); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(am_type.cbFormat == sizeof(WAVEFORMATEX), "got %lu\n", am_type.cbFormat); + wave_format = (WAVEFORMATEX *)am_type.pbFormat; + ok(wave_format->wFormatTag == WAVE_FORMAT_PCM, "got %u\n", wave_format->wFormatTag); + ok(wave_format->wBitsPerSample == 16, "got %u\n", wave_format->wBitsPerSample); + ok(wave_format->nBlockAlign == 0, "got %u\n", wave_format->nBlockAlign); + ok(wave_format->cbSize == 0, "got %u\n", wave_format->cbSize); + CoTaskMemFree(am_type.pbFormat); + IMFMediaType_DeleteAllItems(media_type); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, 16); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(am_type.cbFormat == sizeof(WAVEFORMATEX), "got %lu\n", am_type.cbFormat); + wave_format = (WAVEFORMATEX *)am_type.pbFormat; + ok(wave_format->wFormatTag == WAVE_FORMAT_PCM, "got %u\n", wave_format->wFormatTag); + ok(wave_format->nBlockAlign == 16, "got %u\n", wave_format->nBlockAlign); + ok(wave_format->cbSize == 0, "got %u\n", wave_format->cbSize); + CoTaskMemFree(am_type.pbFormat); + IMFMediaType_DeleteAllItems(media_type); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(am_type.cbFormat == sizeof(WAVEFORMATEX), "got %lu\n", am_type.cbFormat); + wave_format = (WAVEFORMATEX *)am_type.pbFormat; + ok(wave_format->wFormatTag == WAVE_FORMAT_PCM, "got %u\n", wave_format->wFormatTag); + ok(wave_format->nSamplesPerSec == 44100, "got %lu\n", wave_format->nSamplesPerSec); + ok(wave_format->cbSize == 0, "got %u\n", wave_format->cbSize); + CoTaskMemFree(am_type.pbFormat); + IMFMediaType_DeleteAllItems(media_type); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 176400); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(am_type.cbFormat == sizeof(WAVEFORMATEX), "got %lu\n", am_type.cbFormat); + wave_format = (WAVEFORMATEX *)am_type.pbFormat; + ok(wave_format->wFormatTag == WAVE_FORMAT_PCM, "got %u\n", wave_format->wFormatTag); + ok(wave_format->nAvgBytesPerSec == 176400, "got %lu\n", wave_format->nAvgBytesPerSec); + ok(wave_format->cbSize == 0, "got %u\n", wave_format->cbSize); + CoTaskMemFree(am_type.pbFormat); + IMFMediaType_DeleteAllItems(media_type); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_NUM_CHANNELS, 3); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(am_type.cbFormat == sizeof(WAVEFORMATEXTENSIBLE), "got %lu\n", am_type.cbFormat); + wave_format_ext = (WAVEFORMATEXTENSIBLE *)am_type.pbFormat; + ok(wave_format_ext->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "got %u\n", wave_format_ext->Format.wFormatTag); + ok(wave_format_ext->Format.nChannels == 3, "got %u\n", wave_format_ext->Format.nChannels); + ok(IsEqualGUID(&wave_format_ext->SubFormat, &MFAudioFormat_PCM), + "got %s\n", debugstr_guid(&wave_format_ext->SubFormat)); + ok(wave_format_ext->dwChannelMask == 7, "got %#lx\n", wave_format_ext->dwChannelMask); + ok(wave_format_ext->Samples.wSamplesPerBlock == 0, "got %u\n", + wave_format_ext->Samples.wSamplesPerBlock); + ok(wave_format_ext->Format.cbSize == sizeof(*wave_format_ext) - sizeof(*wave_format), + "got %u\n", wave_format_ext->Format.cbSize); + CoTaskMemFree(am_type.pbFormat); + IMFMediaType_DeleteAllItems(media_type); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_CHANNEL_MASK, 3); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(am_type.cbFormat == sizeof(WAVEFORMATEXTENSIBLE), "got %lu\n", am_type.cbFormat); + wave_format_ext = (WAVEFORMATEXTENSIBLE *)am_type.pbFormat; + ok(wave_format_ext->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, + "got %u\n", wave_format_ext->Format.wFormatTag); + ok(IsEqualGUID(&wave_format_ext->SubFormat, &MFAudioFormat_PCM), + "got %s\n", debugstr_guid(&wave_format_ext->SubFormat)); + ok(wave_format_ext->dwChannelMask == 3, "got %#lx\n", wave_format_ext->dwChannelMask); + ok(wave_format_ext->Samples.wSamplesPerBlock == 0, "got %u\n", + wave_format_ext->Samples.wSamplesPerBlock); + ok(wave_format_ext->Format.cbSize == sizeof(*wave_format_ext) - sizeof(*wave_format), + "got %u\n", wave_format_ext->Format.cbSize); + CoTaskMemFree(am_type.pbFormat); + IMFMediaType_DeleteAllItems(media_type); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, 3); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_SAMPLES_PER_BLOCK, 4); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(am_type.cbFormat == sizeof(WAVEFORMATEXTENSIBLE), "got %lu\n", am_type.cbFormat); + wave_format_ext = (WAVEFORMATEXTENSIBLE *)am_type.pbFormat; + ok(wave_format_ext->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, + "got %u\n", wave_format_ext->Format.wFormatTag); + ok(IsEqualGUID(&wave_format_ext->SubFormat, &MFAudioFormat_PCM), + "got %s\n", debugstr_guid(&wave_format_ext->SubFormat)); + ok(wave_format_ext->dwChannelMask == 0, "got %#lx\n", wave_format_ext->dwChannelMask); + ok(wave_format_ext->Samples.wSamplesPerBlock == 4, "got %u\n", + wave_format_ext->Samples.wSamplesPerBlock); + ok(wave_format_ext->Format.cbSize == sizeof(*wave_format_ext) - sizeof(*wave_format), + "got %u\n", wave_format_ext->Format.cbSize); + CoTaskMemFree(am_type.pbFormat); + IMFMediaType_DeleteAllItems(media_type); + + + /* test VIDEOINFOHEADER mapping */ + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetBlob(media_type, &MF_MT_USER_DATA, dummy_user_data, sizeof(dummy_user_data)); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(am_type.cbFormat == sizeof(VIDEOINFOHEADER) + sizeof(dummy_user_data), "got %lu\n", am_type.cbFormat); + video_info = (VIDEOINFOHEADER *)am_type.pbFormat; + ok(video_info->rcSource.right == 0, "got %lu\n", video_info->rcSource.right); + ok(video_info->rcSource.bottom == 0, "got %lu\n", video_info->rcSource.bottom); + ok(video_info->rcTarget.right == 0, "got %lu\n", video_info->rcTarget.right); + ok(video_info->rcTarget.bottom == 0, "got %lu\n", video_info->rcTarget.bottom); + ok(video_info->dwBitRate == 0, "got %lu\n", video_info->dwBitRate); + ok(video_info->dwBitErrorRate == 0, "got %lu\n", video_info->dwBitErrorRate); + ok(video_info->AvgTimePerFrame == 0, "got %I64d\n", video_info->AvgTimePerFrame); + ok(video_info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER) + sizeof(dummy_user_data), + "got %lu\n", video_info->bmiHeader.biSize); + ok(video_info->bmiHeader.biWidth == 0, "got %lu\n", video_info->bmiHeader.biWidth); + ok(video_info->bmiHeader.biHeight == 0, "got %lu\n", video_info->bmiHeader.biHeight); + ok(video_info->bmiHeader.biPlanes == 1, "got %u\n", video_info->bmiHeader.biPlanes); + ok(video_info->bmiHeader.biBitCount == 32, "got %u\n", video_info->bmiHeader.biBitCount); + ok(video_info->bmiHeader.biCompression == BI_RGB, "got %lu\n", video_info->bmiHeader.biCompression); + ok(video_info->bmiHeader.biSizeImage == 0, "got %lu\n", video_info->bmiHeader.biSizeImage); + ok(!memcmp(video_info + 1, dummy_user_data, sizeof(dummy_user_data)), + "got unexpected data\n"); + CoTaskMemFree(am_type.pbFormat); + IMFMediaType_DeleteAllItems(media_type); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, 1); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(am_type.bFixedSizeSamples == 1, "got %u.\n", am_type.bFixedSizeSamples); + CoTaskMemFree(am_type.pbFormat); + IMFMediaType_DeleteAllItems(media_type); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_SAMPLE_SIZE, 123456); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(am_type.lSampleSize == 123456, "got %lu.\n", am_type.lSampleSize); + CoTaskMemFree(am_type.pbFormat); + IMFMediaType_DeleteAllItems(media_type); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + video_info = (VIDEOINFOHEADER *)am_type.pbFormat; + ok(video_info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER), "got %lu\n", video_info->bmiHeader.biSize); + ok(video_info->bmiHeader.biBitCount == 32, "got %u\n", video_info->bmiHeader.biBitCount); + ok(video_info->bmiHeader.biCompression == BI_RGB, "got %lu\n", video_info->bmiHeader.biCompression); + CoTaskMemFree(am_type.pbFormat); + IMFMediaType_DeleteAllItems(media_type); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB565); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + video_info = (VIDEOINFOHEADER *)am_type.pbFormat; + ok(video_info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER), "got %lu\n", video_info->bmiHeader.biSize); + ok(video_info->bmiHeader.biBitCount == 16, "got %u\n", video_info->bmiHeader.biBitCount); + ok(video_info->bmiHeader.biCompression == BI_BITFIELDS, "got %lu\n", video_info->bmiHeader.biCompression); + CoTaskMemFree(am_type.pbFormat); + IMFMediaType_DeleteAllItems(media_type); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_NV12); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + video_info = (VIDEOINFOHEADER *)am_type.pbFormat; + ok(video_info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER), "got %lu\n", video_info->bmiHeader.biSize); + ok(video_info->bmiHeader.biBitCount == 12, "got %u\n", video_info->bmiHeader.biBitCount); + ok(video_info->bmiHeader.biCompression == MFVideoFormat_NV12.Data1, "got %lu\n", video_info->bmiHeader.biCompression); + CoTaskMemFree(am_type.pbFormat); + IMFMediaType_DeleteAllItems(media_type); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_WMV2); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + video_info = (VIDEOINFOHEADER *)am_type.pbFormat; + ok(video_info->bmiHeader.biSize == sizeof(BITMAPINFOHEADER), "got %lu\n", video_info->bmiHeader.biSize); + ok(video_info->bmiHeader.biBitCount == 0, "got %u\n", video_info->bmiHeader.biBitCount); + ok(video_info->bmiHeader.biCompression == MFVideoFormat_WMV2.Data1, "got %lu\n", video_info->bmiHeader.biCompression); + CoTaskMemFree(am_type.pbFormat); + IMFMediaType_DeleteAllItems(media_type); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_NV12); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_RATE, (UINT64)123 << 32 | 456); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + video_info = (VIDEOINFOHEADER *)am_type.pbFormat; + ok(video_info->AvgTimePerFrame == 37073171, "got %I64d\n", video_info->AvgTimePerFrame); + CoTaskMemFree(am_type.pbFormat); + IMFMediaType_DeleteAllItems(media_type); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_NV12); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AVG_BITRATE, 123456); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AVG_BIT_ERROR_RATE, 654321); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + video_info = (VIDEOINFOHEADER *)am_type.pbFormat; + ok(video_info->dwBitRate == 123456, "got %lu\n", video_info->dwBitRate); + ok(video_info->dwBitErrorRate == 654321, "got %lu\n", video_info->dwBitErrorRate); + CoTaskMemFree(am_type.pbFormat); + IMFMediaType_DeleteAllItems(media_type); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_NV12); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_SAMPLE_SIZE, 123456); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + video_info = (VIDEOINFOHEADER *)am_type.pbFormat; + ok(video_info->bmiHeader.biSizeImage == 123456, "got %lu\n", video_info->bmiHeader.biSizeImage); + CoTaskMemFree(am_type.pbFormat); + IMFMediaType_DeleteAllItems(media_type); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, (UINT64)123 << 32 | 456); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + video_info = (VIDEOINFOHEADER *)am_type.pbFormat; + ok(video_info->bmiHeader.biWidth == 123, "got %lu\n", video_info->bmiHeader.biWidth); + ok(video_info->bmiHeader.biHeight == 456, "got %lu\n", video_info->bmiHeader.biHeight); + ok(video_info->bmiHeader.biSizeImage == 224352, "got %lu\n", video_info->bmiHeader.biSizeImage); + CoTaskMemFree(am_type.pbFormat); + IMFMediaType_DeleteAllItems(media_type); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, (UINT64)123 << 32 | 456); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetBlob(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, (BYTE *)&aperture, sizeof(aperture)); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_SAMPLE_SIZE, 123456); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + video_info = (VIDEOINFOHEADER *)am_type.pbFormat; + ok(video_info->rcSource.left == 0, "got %lu\n", video_info->rcSource.left); + ok(video_info->rcSource.right == 0, "got %lu\n", video_info->rcSource.right); + ok(video_info->rcSource.top == 0, "got %lu\n", video_info->rcSource.top); + ok(video_info->rcSource.bottom == 0, "got %lu\n", video_info->rcSource.bottom); + ok(video_info->rcTarget.left == 0, "got %lu\n", video_info->rcTarget.left); + ok(video_info->rcTarget.right == 0, "got %lu\n", video_info->rcTarget.right); + ok(video_info->rcTarget.top == 0, "got %lu\n", video_info->rcTarget.top); + ok(video_info->rcTarget.bottom == 0, "got %lu\n", video_info->rcTarget.bottom); + ok(video_info->bmiHeader.biWidth == 123, "got %lu\n", video_info->bmiHeader.biWidth); + ok(video_info->bmiHeader.biHeight == 456, "got %lu\n", video_info->bmiHeader.biHeight); + ok(video_info->bmiHeader.biSizeImage == 224352, "got %lu\n", video_info->bmiHeader.biSizeImage); + CoTaskMemFree(am_type.pbFormat); + IMFMediaType_DeleteAllItems(media_type); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, (UINT64)123 << 32 | 456); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, -984); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + video_info = (VIDEOINFOHEADER *)am_type.pbFormat; + ok(video_info->bmiHeader.biWidth == 246, "got %lu\n", video_info->bmiHeader.biWidth); + ok(video_info->bmiHeader.biHeight == 456, "got %ld\n", video_info->bmiHeader.biHeight); + ok(video_info->bmiHeader.biSizeImage == 448704, "got %lu\n", video_info->bmiHeader.biSizeImage); + CoTaskMemFree(am_type.pbFormat); + IMFMediaType_DeleteAllItems(media_type); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, (UINT64)123 << 32 | 456); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, 984); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + video_info = (VIDEOINFOHEADER *)am_type.pbFormat; + ok(video_info->bmiHeader.biWidth == 246, "got %lu\n", video_info->bmiHeader.biWidth); + ok(video_info->bmiHeader.biHeight == -456, "got %ld\n", video_info->bmiHeader.biHeight); + ok(video_info->bmiHeader.biSizeImage == 448704, "got %lu\n", video_info->bmiHeader.biSizeImage); + CoTaskMemFree(am_type.pbFormat); + IMFMediaType_DeleteAllItems(media_type); + +skip_tests: + IMFMediaType_Release(media_type); +} + static void test_MFCreateDXSurfaceBuffer(void) { IDirect3DSurface9 *backbuffer = NULL, *surface; @@ -9767,6 +10267,7 @@ START_TEST(mfplat) test_MFCreateMediaBufferFromMediaType(); test_MFInitMediaTypeFromWaveFormatEx(); test_MFCreateMFVideoFormatFromMFMediaType(); + test_MFInitAMMediaTypeFromMFMediaType(); test_MFCreateDXSurfaceBuffer(); test_MFCreateTrackedSample(); test_MFFrameRateToAverageTimePerFrame();
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/tests/mfplat.c | 39 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+)
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index bb01686fb9c..e8a38b8cbaa 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -7526,6 +7526,44 @@ skip_tests: IMFMediaType_Release(media_type); }
+static void test_MFCreateAMMediaTypeFromMFMediaType(void) +{ + IMFMediaType *media_type; + AM_MEDIA_TYPE *am_type; + HRESULT hr; + + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr); + + hr = MFCreateAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + todo_wine ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFCreateAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + todo_wine ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFCreateAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + todo_wine ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFCreateAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (hr != S_OK) goto skip_tests; + ok(IsEqualGUID(&am_type->majortype, &MFMediaType_Audio), "got %s.\n", debugstr_guid(&am_type->majortype)); + ok(IsEqualGUID(&am_type->subtype, &MFAudioFormat_PCM), "got %s.\n", debugstr_guid(&am_type->subtype)); + ok(IsEqualGUID(&am_type->formattype, &FORMAT_WaveFormatEx), "got %s.\n", debugstr_guid(&am_type->formattype)); + ok(am_type->cbFormat == sizeof(WAVEFORMATEX), "got %lu\n", am_type->cbFormat); + CoTaskMemFree(am_type->pbFormat); + CoTaskMemFree(am_type); + +skip_tests: + IMFMediaType_Release(media_type); +} + static void test_MFCreateDXSurfaceBuffer(void) { IDirect3DSurface9 *backbuffer = NULL, *surface; @@ -10268,6 +10306,7 @@ START_TEST(mfplat) test_MFInitMediaTypeFromWaveFormatEx(); test_MFCreateMFVideoFormatFromMFMediaType(); test_MFInitAMMediaTypeFromMFMediaType(); + test_MFCreateAMMediaTypeFromMFMediaType(); test_MFCreateDXSurfaceBuffer(); test_MFCreateTrackedSample(); test_MFFrameRateToAverageTimePerFrame();
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/tests/mfplat.c | 76 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+)
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index e8a38b8cbaa..8379486d5bd 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -7564,6 +7564,81 @@ skip_tests: IMFMediaType_Release(media_type); }
+static void test_IMFMediaType_GetRepresentation(void) +{ + WAVEFORMATEX wfx = {.wFormatTag = WAVE_FORMAT_PCM}; + IMFMediaType *media_type; + AM_MEDIA_TYPE *am_type; + HRESULT hr; + + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr); + + hr = IMFMediaType_GetRepresentation(media_type, GUID_NULL, (void **)&am_type); + todo_wine ok(hr == MF_E_UNSUPPORTED_REPRESENTATION, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetRepresentation(media_type, AM_MEDIA_TYPE_REPRESENTATION, (void **)&am_type); + todo_wine ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetRepresentation(media_type, AM_MEDIA_TYPE_REPRESENTATION, (void **)&am_type); + todo_wine ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetRepresentation(media_type, AM_MEDIA_TYPE_REPRESENTATION, (void **)&am_type); + todo_wine ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetRepresentation(media_type, FORMAT_VideoInfo, (void **)&am_type); + todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetRepresentation(media_type, AM_MEDIA_TYPE_REPRESENTATION, (void **)&am_type); + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (hr != S_OK) goto skip_tests; + ok(IsEqualGUID(&am_type->majortype, &MFMediaType_Audio), "got %s.\n", debugstr_guid(&am_type->majortype)); + ok(IsEqualGUID(&am_type->subtype, &MFAudioFormat_PCM), "got %s.\n", debugstr_guid(&am_type->subtype)); + ok(IsEqualGUID(&am_type->formattype, &FORMAT_WaveFormatEx), "got %s.\n", debugstr_guid(&am_type->formattype)); + ok(am_type->cbFormat == sizeof(WAVEFORMATEX), "got %lu\n", am_type->cbFormat); + hr = IMFMediaType_FreeRepresentation(media_type, IID_IUnknown /* invalid format */, am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFMediaType_Release(media_type); + + hr = MFCreateAudioMediaType(&wfx, (IMFAudioMediaType **)&media_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetRepresentation(media_type, GUID_NULL, (void **)&am_type); + ok(hr == MF_E_UNSUPPORTED_REPRESENTATION, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetRepresentation(media_type, FORMAT_VideoInfo, (void **)&am_type); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetRepresentation(media_type, AM_MEDIA_TYPE_REPRESENTATION, (void **)&am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&am_type->majortype, &MFMediaType_Audio), "got %s.\n", debugstr_guid(&am_type->majortype)); + ok(IsEqualGUID(&am_type->subtype, &MFAudioFormat_PCM), "got %s.\n", debugstr_guid(&am_type->subtype)); + ok(IsEqualGUID(&am_type->formattype, &FORMAT_WaveFormatEx), "got %s.\n", debugstr_guid(&am_type->formattype)); + ok(am_type->cbFormat == sizeof(WAVEFORMATEX), "got %lu\n", am_type->cbFormat); + hr = IMFMediaType_FreeRepresentation(media_type, AM_MEDIA_TYPE_REPRESENTATION, am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFMediaType_Release(media_type); + + hr = MFCreateVideoMediaTypeFromSubtype(&MFVideoFormat_RGB32, (IMFVideoMediaType **)&media_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetRepresentation(media_type, GUID_NULL, (void **)&am_type); + ok(hr == MF_E_UNSUPPORTED_REPRESENTATION, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetRepresentation(media_type, FORMAT_WaveFormatEx, (void **)&am_type); + ok(hr == MF_E_UNSUPPORTED_REPRESENTATION, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetRepresentation(media_type, AM_MEDIA_TYPE_REPRESENTATION, (void **)&am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&am_type->majortype, &MFMediaType_Video), "got %s.\n", debugstr_guid(&am_type->majortype)); + ok(IsEqualGUID(&am_type->subtype, &MEDIASUBTYPE_RGB32), "got %s.\n", debugstr_guid(&am_type->subtype)); + ok(IsEqualGUID(&am_type->formattype, &FORMAT_VideoInfo), "got %s.\n", debugstr_guid(&am_type->formattype)); + ok(am_type->cbFormat == sizeof(VIDEOINFOHEADER), "got %lu\n", am_type->cbFormat); + hr = IMFMediaType_FreeRepresentation(media_type, AM_MEDIA_TYPE_REPRESENTATION, am_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + +skip_tests: + IMFMediaType_Release(media_type); +} + static void test_MFCreateDXSurfaceBuffer(void) { IDirect3DSurface9 *backbuffer = NULL, *surface; @@ -10307,6 +10382,7 @@ START_TEST(mfplat) test_MFCreateMFVideoFormatFromMFMediaType(); test_MFInitAMMediaTypeFromMFMediaType(); test_MFCreateAMMediaTypeFromMFMediaType(); + test_IMFMediaType_GetRepresentation(); test_MFCreateDXSurfaceBuffer(); test_MFCreateTrackedSample(); test_MFFrameRateToAverageTimePerFrame();
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/mediatype.c | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index 437e5aba869..c3798adee5a 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -3601,30 +3601,33 @@ static HRESULT mf_get_stride_for_bitmap_info_header(DWORD fourcc, const BITMAPIN static const GUID * get_mf_subtype_for_am_subtype(const GUID *subtype) { static const GUID null; + GUID base;
+ if (IsEqualGUID(subtype, &MEDIASUBTYPE_A2R10G10B10)) + return &MFVideoFormat_A2R10G10B10; + if (IsEqualGUID(subtype, &MEDIASUBTYPE_ARGB32)) + return &MFVideoFormat_ARGB32; + if (IsEqualGUID(subtype, &MEDIASUBTYPE_RGB8)) + return &MFVideoFormat_RGB8; + if (IsEqualGUID(subtype, &MEDIASUBTYPE_RGB555)) + return &MFVideoFormat_RGB555; + if (IsEqualGUID(subtype, &MEDIASUBTYPE_RGB565)) + return &MFVideoFormat_RGB565; + if (IsEqualGUID(subtype, &MEDIASUBTYPE_RGB24)) + return &MFVideoFormat_RGB24; if (IsEqualGUID(subtype, &MEDIASUBTYPE_RGB32)) return &MFVideoFormat_RGB32; - else if (IsEqualGUID(subtype, &MEDIASUBTYPE_ARGB32)) - return &MFVideoFormat_ARGB32; - else if (IsEqualGUID(subtype, &MEDIASUBTYPE_I420)) - return &MFVideoFormat_I420; - else if (IsEqualGUID(subtype, &MEDIASUBTYPE_AYUV)) - return &MFVideoFormat_AYUV; - else if (IsEqualGUID(subtype, &MEDIASUBTYPE_YV12)) - return &MFVideoFormat_YV12; - else if (IsEqualGUID(subtype, &MEDIASUBTYPE_YUY2)) - return &MFVideoFormat_YUY2; - else if (IsEqualGUID(subtype, &MEDIASUBTYPE_UYVY)) - return &MFVideoFormat_UYVY; - else if (IsEqualGUID(subtype, &MEDIASUBTYPE_YVYU)) - return &MFVideoFormat_YVYU; - else if (IsEqualGUID(subtype, &MEDIASUBTYPE_NV12)) - return &MFVideoFormat_NV12; - else + + base = *subtype; + base.Data1 = 0; + + if (memcmp(&base, &MFVideoFormat_Base, sizeof(base))) { FIXME("Unknown subtype %s.\n", debugstr_guid(subtype)); return &null; } + + return subtype; }
/***********************************************************************
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/mediatype.c | 64 ++++++++++++++++++++--------------------- 1 file changed, 32 insertions(+), 32 deletions(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index c3798adee5a..24457c1bb2d 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -2618,7 +2618,7 @@ HRESULT WINAPI MFCreatePresentationDescriptor(DWORD count, IMFStreamDescriptor * struct uncompressed_video_format { const GUID *subtype; - unsigned char bytes_per_pixel; + unsigned char bpp; unsigned char alignment; unsigned char bottom_up; unsigned char yuv; @@ -2633,35 +2633,35 @@ static int __cdecl uncompressed_video_format_compare(const void *a, const void *
static const struct uncompressed_video_format video_formats[] = { - { &MFVideoFormat_RGB24, 3, 3, 1, 0 }, - { &MFVideoFormat_ARGB32, 4, 3, 1, 0 }, - { &MFVideoFormat_RGB32, 4, 3, 1, 0 }, - { &MFVideoFormat_RGB565, 2, 3, 1, 0 }, - { &MFVideoFormat_RGB555, 2, 3, 1, 0 }, - { &MFVideoFormat_A2R10G10B10, 4, 3, 1, 0 }, - { &MFVideoFormat_RGB8, 1, 3, 1, 0 }, - { &MFVideoFormat_L8, 1, 3, 1, 0 }, - { &MFVideoFormat_AYUV, 4, 3, 0, 1 }, - { &MFVideoFormat_I420, 1, 0, 0, 1 }, - { &MFVideoFormat_IMC1, 2, 3, 0, 1 }, - { &MFVideoFormat_IMC2, 1, 0, 0, 1 }, - { &MFVideoFormat_IMC3, 2, 3, 0, 1 }, - { &MFVideoFormat_IMC4, 1, 0, 0, 1 }, - { &MFVideoFormat_IYUV, 1, 0, 0, 1 }, - { &MFVideoFormat_NV11, 1, 0, 0, 1 }, - { &MFVideoFormat_NV12, 1, 0, 0, 1 }, - { &MFVideoFormat_D16, 2, 3, 0, 0 }, - { &MFVideoFormat_L16, 2, 3, 0, 0 }, - { &MFVideoFormat_UYVY, 2, 0, 0, 1 }, - { &MFVideoFormat_YUY2, 2, 0, 0, 1 }, - { &MFVideoFormat_YV12, 1, 0, 0, 1 }, - { &MFVideoFormat_YVYU, 2, 0, 0, 1 }, - { &MFVideoFormat_A16B16G16R16F, 8, 3, 1, 0 }, - { &MEDIASUBTYPE_RGB8, 1, 3, 1, 0 }, - { &MEDIASUBTYPE_RGB565, 2, 3, 1, 0 }, - { &MEDIASUBTYPE_RGB555, 2, 3, 1, 0 }, - { &MEDIASUBTYPE_RGB24, 3, 3, 1, 0 }, - { &MEDIASUBTYPE_RGB32, 4, 3, 1, 0 }, + { &MFVideoFormat_RGB24, 24, 3, 1, 0 }, + { &MFVideoFormat_ARGB32, 32, 3, 1, 0 }, + { &MFVideoFormat_RGB32, 32, 3, 1, 0 }, + { &MFVideoFormat_RGB565, 16, 3, 1, 0 }, + { &MFVideoFormat_RGB555, 16, 3, 1, 0 }, + { &MFVideoFormat_A2R10G10B10, 32, 3, 1, 0 }, + { &MFVideoFormat_RGB8, 8, 3, 1, 0 }, + { &MFVideoFormat_L8, 8, 3, 1, 0 }, + { &MFVideoFormat_AYUV, 32, 3, 0, 1 }, + { &MFVideoFormat_I420, 12, 0, 0, 1 }, + { &MFVideoFormat_IMC1, 16, 3, 0, 1 }, + { &MFVideoFormat_IMC2, 12, 0, 0, 1 }, + { &MFVideoFormat_IMC3, 16, 3, 0, 1 }, + { &MFVideoFormat_IMC4, 12, 0, 0, 1 }, + { &MFVideoFormat_IYUV, 12, 0, 0, 1 }, + { &MFVideoFormat_NV11, 12, 0, 0, 1 }, + { &MFVideoFormat_NV12, 12, 0, 0, 1 }, + { &MFVideoFormat_D16, 16, 3, 0, 0 }, + { &MFVideoFormat_L16, 16, 3, 0, 0 }, + { &MFVideoFormat_UYVY, 16, 0, 0, 1 }, + { &MFVideoFormat_YUY2, 16, 0, 0, 1 }, + { &MFVideoFormat_YV12, 12, 0, 0, 1 }, + { &MFVideoFormat_YVYU, 16, 0, 0, 1 }, + { &MFVideoFormat_A16B16G16R16F, 64, 3, 1, 0 }, + { &MEDIASUBTYPE_RGB8, 8, 3, 1, 0 }, + { &MEDIASUBTYPE_RGB565, 16, 3, 1, 0 }, + { &MEDIASUBTYPE_RGB555, 16, 3, 1, 0 }, + { &MEDIASUBTYPE_RGB24, 24, 3, 1, 0 }, + { &MEDIASUBTYPE_RGB32, 32, 3, 1, 0 }, };
static struct uncompressed_video_format *mf_get_video_format(const GUID *subtype) @@ -2672,7 +2672,7 @@ static struct uncompressed_video_format *mf_get_video_format(const GUID *subtype
static unsigned int mf_get_stride_for_format(const struct uncompressed_video_format *format, unsigned int width) { - return (width * format->bytes_per_pixel + format->alignment) & ~format->alignment; + return (width * (format->bpp / 8) + format->alignment) & ~format->alignment; }
unsigned int mf_format_get_stride(const GUID *subtype, unsigned int width, BOOL *is_yuv) @@ -2747,7 +2747,7 @@ HRESULT WINAPI MFCalculateImageSize(REFGUID subtype, UINT32 width, UINT32 height case D3DFMT_L8: case D3DFMT_L16: case D3DFMT_D16: - *size = width * format->bytes_per_pixel * height; + *size = width * (format->bpp / 8) * height; break; default: stride = mf_get_stride_for_format(format, width);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/mediatype.c | 304 +++++++++++++++++++++++++++++++++---- dlls/mfplat/tests/mfplat.c | 20 ++- 2 files changed, 282 insertions(+), 42 deletions(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index 24457c1bb2d..9e26b513250 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -19,6 +19,7 @@ #define COBJMACROS
#include "mfplat_private.h" +#include <math.h>
#include "dxva2api.h" #include "uuids.h" @@ -35,6 +36,37 @@ DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC1, MAKEFOURCC('I','M','C','1')); DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC2, MAKEFOURCC('I','M','C','2')); DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC3, MAKEFOURCC('I','M','C','3')); DEFINE_MEDIATYPE_GUID(MFVideoFormat_IMC4, MAKEFOURCC('I','M','C','4')); +DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); + +static const UINT32 default_channel_mask[7] = +{ + 0, + SPEAKER_FRONT_LEFT, + SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT, + SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | SPEAKER_FRONT_CENTER, + KSAUDIO_SPEAKER_QUAD, + KSAUDIO_SPEAKER_QUAD | SPEAKER_FRONT_CENTER, + KSAUDIO_SPEAKER_5POINT1, +}; + +static GUID get_am_subtype_for_mf_subtype(GUID subtype) +{ + if (IsEqualGUID(&subtype, &MFVideoFormat_A2R10G10B10)) + return MEDIASUBTYPE_A2R10G10B10; + if (IsEqualGUID(&subtype, &MFVideoFormat_ARGB32)) + return MEDIASUBTYPE_ARGB32; + if (IsEqualGUID(&subtype, &MFVideoFormat_RGB8)) + return MEDIASUBTYPE_RGB8; + if (IsEqualGUID(&subtype, &MFVideoFormat_RGB555)) + return MEDIASUBTYPE_RGB555; + if (IsEqualGUID(&subtype, &MFVideoFormat_RGB565)) + return MEDIASUBTYPE_RGB565; + if (IsEqualGUID(&subtype, &MFVideoFormat_RGB24)) + return MEDIASUBTYPE_RGB24; + if (IsEqualGUID(&subtype, &MFVideoFormat_RGB32)) + return MEDIASUBTYPE_RGB32; + return subtype; +}
struct media_type { @@ -2622,6 +2654,7 @@ struct uncompressed_video_format unsigned char alignment; unsigned char bottom_up; unsigned char yuv; + int compression; };
static int __cdecl uncompressed_video_format_compare(const void *a, const void *b) @@ -2633,35 +2666,35 @@ static int __cdecl uncompressed_video_format_compare(const void *a, const void *
static const struct uncompressed_video_format video_formats[] = { - { &MFVideoFormat_RGB24, 24, 3, 1, 0 }, - { &MFVideoFormat_ARGB32, 32, 3, 1, 0 }, - { &MFVideoFormat_RGB32, 32, 3, 1, 0 }, - { &MFVideoFormat_RGB565, 16, 3, 1, 0 }, - { &MFVideoFormat_RGB555, 16, 3, 1, 0 }, - { &MFVideoFormat_A2R10G10B10, 32, 3, 1, 0 }, - { &MFVideoFormat_RGB8, 8, 3, 1, 0 }, - { &MFVideoFormat_L8, 8, 3, 1, 0 }, - { &MFVideoFormat_AYUV, 32, 3, 0, 1 }, - { &MFVideoFormat_I420, 12, 0, 0, 1 }, - { &MFVideoFormat_IMC1, 16, 3, 0, 1 }, - { &MFVideoFormat_IMC2, 12, 0, 0, 1 }, - { &MFVideoFormat_IMC3, 16, 3, 0, 1 }, - { &MFVideoFormat_IMC4, 12, 0, 0, 1 }, - { &MFVideoFormat_IYUV, 12, 0, 0, 1 }, - { &MFVideoFormat_NV11, 12, 0, 0, 1 }, - { &MFVideoFormat_NV12, 12, 0, 0, 1 }, - { &MFVideoFormat_D16, 16, 3, 0, 0 }, - { &MFVideoFormat_L16, 16, 3, 0, 0 }, - { &MFVideoFormat_UYVY, 16, 0, 0, 1 }, - { &MFVideoFormat_YUY2, 16, 0, 0, 1 }, - { &MFVideoFormat_YV12, 12, 0, 0, 1 }, - { &MFVideoFormat_YVYU, 16, 0, 0, 1 }, - { &MFVideoFormat_A16B16G16R16F, 64, 3, 1, 0 }, - { &MEDIASUBTYPE_RGB8, 8, 3, 1, 0 }, - { &MEDIASUBTYPE_RGB565, 16, 3, 1, 0 }, - { &MEDIASUBTYPE_RGB555, 16, 3, 1, 0 }, - { &MEDIASUBTYPE_RGB24, 24, 3, 1, 0 }, - { &MEDIASUBTYPE_RGB32, 32, 3, 1, 0 }, + { &MFVideoFormat_RGB24, 24, 3, 1, 0, BI_RGB }, + { &MFVideoFormat_ARGB32, 32, 3, 1, 0, BI_RGB }, + { &MFVideoFormat_RGB32, 32, 3, 1, 0, BI_RGB }, + { &MFVideoFormat_RGB565, 16, 3, 1, 0, BI_BITFIELDS }, + { &MFVideoFormat_RGB555, 16, 3, 1, 0, BI_RGB }, + { &MFVideoFormat_A2R10G10B10, 32, 3, 1, 0, -1 }, + { &MFVideoFormat_RGB8, 8, 3, 1, 0, BI_RGB }, + { &MFVideoFormat_L8, 8, 3, 1, 0, -1 }, + { &MFVideoFormat_AYUV, 32, 3, 0, 1, -1 }, + { &MFVideoFormat_I420, 12, 0, 0, 1, -1 }, + { &MFVideoFormat_IMC1, 16, 3, 0, 1, -1 }, + { &MFVideoFormat_IMC2, 12, 0, 0, 1, -1 }, + { &MFVideoFormat_IMC3, 16, 3, 0, 1, -1 }, + { &MFVideoFormat_IMC4, 12, 0, 0, 1, -1 }, + { &MFVideoFormat_IYUV, 12, 0, 0, 1, -1 }, + { &MFVideoFormat_NV11, 12, 0, 0, 1, -1 }, + { &MFVideoFormat_NV12, 12, 0, 0, 1, -1 }, + { &MFVideoFormat_D16, 16, 3, 0, 0, -1 }, + { &MFVideoFormat_L16, 16, 3, 0, 0, -1 }, + { &MFVideoFormat_UYVY, 16, 0, 0, 1, -1 }, + { &MFVideoFormat_YUY2, 16, 0, 0, 1, -1 }, + { &MFVideoFormat_YV12, 12, 0, 0, 1, -1 }, + { &MFVideoFormat_YVYU, 16, 0, 0, 1, -1 }, + { &MFVideoFormat_A16B16G16R16F, 64, 3, 1, 0, -1 }, + { &MEDIASUBTYPE_RGB8, 8, 3, 1, 0, BI_RGB }, + { &MEDIASUBTYPE_RGB565, 16, 3, 1, 0, BI_BITFIELDS }, + { &MEDIASUBTYPE_RGB555, 16, 3, 1, 0, BI_RGB }, + { &MEDIASUBTYPE_RGB24, 24, 3, 1, 0, BI_RGB }, + { &MEDIASUBTYPE_RGB32, 32, 3, 1, 0, BI_RGB }, };
static struct uncompressed_video_format *mf_get_video_format(const GUID *subtype) @@ -3682,13 +3715,222 @@ HRESULT WINAPI MFInitMediaTypeFromVideoInfoHeader(IMFMediaType *media_type, cons return hr; }
+static HRESULT init_am_media_type_audio_format(AM_MEDIA_TYPE *am_type, UINT32 user_size, IMFMediaType *media_type) +{ + UINT32 num_channels, value; + HRESULT hr; + + if (IsEqualGUID(&am_type->formattype, &FORMAT_VideoInfo) + || IsEqualGUID(&am_type->formattype, &FORMAT_VideoInfo2) + || IsEqualGUID(&am_type->formattype, &FORMAT_MFVideoFormat)) + return E_INVALIDARG; + + if (IsEqualGUID(&am_type->formattype, &FORMAT_WaveFormatEx) + || IsEqualGUID(&am_type->formattype, &GUID_NULL)) + { + WAVEFORMATEX *format; + + if (FAILED(IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_NUM_CHANNELS, &num_channels))) + num_channels = 0; + + if (SUCCEEDED(IMFMediaType_GetItem(media_type, &MF_MT_AUDIO_CHANNEL_MASK, NULL)) + || SUCCEEDED(IMFMediaType_GetItem(media_type, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, NULL)) + || SUCCEEDED(IMFMediaType_GetItem(media_type, &MF_MT_AUDIO_SAMPLES_PER_BLOCK, NULL)) + || num_channels > 2) + { + WAVEFORMATEXTENSIBLE *format_ext; + + am_type->cbFormat = sizeof(*format_ext) + user_size; + if (!(am_type->pbFormat = CoTaskMemAlloc(am_type->cbFormat))) + return E_OUTOFMEMORY; + format_ext = (WAVEFORMATEXTENSIBLE *)am_type->pbFormat; + memset(format_ext, 0, sizeof(*format_ext)); + + if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_CHANNEL_MASK, &value))) + format_ext->dwChannelMask = value; + else if (num_channels < ARRAY_SIZE(default_channel_mask)) + format_ext->dwChannelMask = default_channel_mask[num_channels]; + + if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, &value))) + format_ext->Samples.wValidBitsPerSample = value; + if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_SAMPLES_PER_BLOCK, &value))) + format_ext->Samples.wSamplesPerBlock = value; + format_ext->SubFormat = am_type->subtype; + + format = &format_ext->Format; + format->wFormatTag = WAVE_FORMAT_EXTENSIBLE; + format->cbSize = sizeof(*format_ext) - sizeof(*format) + user_size; + + if (user_size && FAILED(hr = IMFMediaType_GetBlob(media_type, &MF_MT_USER_DATA, + (BYTE *)(format_ext + 1), user_size, NULL))) + return hr; + } + else + { + am_type->cbFormat = sizeof(*format) + user_size; + if (!(am_type->pbFormat = CoTaskMemAlloc(am_type->cbFormat))) + return E_OUTOFMEMORY; + format = (WAVEFORMATEX *)am_type->pbFormat; + memset(format, 0, sizeof(*format)); + + format->wFormatTag = am_type->subtype.Data1; + format->cbSize = user_size; + + if (user_size && FAILED(hr = IMFMediaType_GetBlob(media_type, &MF_MT_USER_DATA, + (BYTE *)(format + 1), user_size, NULL))) + return hr; + } + + format->nChannels = num_channels; + if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &value))) + format->nSamplesPerSec = value; + if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &value))) + format->nAvgBytesPerSec = value; + if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &value))) + format->nBlockAlign = value; + if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &value))) + format->wBitsPerSample = value; + + am_type->subtype = get_am_subtype_for_mf_subtype(am_type->subtype); + am_type->formattype = FORMAT_WaveFormatEx; + } + else + { + WARN("Unknown format %s\n", debugstr_mf_guid(&am_type->formattype)); + am_type->formattype = GUID_NULL; + } + + return S_OK; +} + +static HRESULT init_am_media_type_video_format(AM_MEDIA_TYPE *am_type, UINT32 user_size, IMFMediaType *media_type) +{ + UINT32 image_size, bitrate, sample_size; + UINT64 frame_size, frame_rate; + INT32 width, height; + HRESULT hr; + + if (IsEqualGUID(&am_type->formattype, &FORMAT_WaveFormatEx)) + return E_INVALIDARG; + + if (IsEqualGUID(&am_type->formattype, &FORMAT_MFVideoFormat)) + return MFCreateMFVideoFormatFromMFMediaType(media_type, (MFVIDEOFORMAT **)&am_type->pbFormat, + (UINT32 *)&am_type->cbFormat); + + if (IsEqualGUID(&am_type->formattype, &FORMAT_VideoInfo) + || IsEqualGUID(&am_type->formattype, &GUID_NULL)) + { + struct uncompressed_video_format *video_format = mf_get_video_format(&am_type->subtype); + VIDEOINFOHEADER *format; + + am_type->cbFormat = sizeof(*format) + user_size; + if (!(am_type->pbFormat = CoTaskMemAlloc(am_type->cbFormat))) + return E_OUTOFMEMORY; + format = (VIDEOINFOHEADER *)am_type->pbFormat; + memset(format, 0, sizeof(*format)); + + format->bmiHeader.biSize = sizeof(format->bmiHeader) + user_size; + format->bmiHeader.biPlanes = 1; + format->bmiHeader.biBitCount = video_format ? video_format->bpp : 0; + + if (video_format && video_format->compression != -1) + format->bmiHeader.biCompression = video_format->compression; + else + format->bmiHeader.biCompression = am_type->subtype.Data1; + + if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_AVG_BITRATE, &bitrate))) + format->dwBitRate = bitrate; + if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_AVG_BIT_ERROR_RATE, &bitrate))) + format->dwBitErrorRate = bitrate; + if (SUCCEEDED(IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_RATE, &frame_rate)) && (frame_rate >> 32)) + format->AvgTimePerFrame = round(10000000. * (UINT32)frame_rate / (frame_rate >> 32)); + if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &sample_size))) + format->bmiHeader.biSizeImage = sample_size; + + if (SUCCEEDED(IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &frame_size))) + { + BOOL bottom_up = format->bmiHeader.biCompression == BI_RGB || format->bmiHeader.biCompression == BI_BITFIELDS; + + if (FAILED(IMFMediaType_GetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, (UINT32 *)&width))) + width = (frame_size >> 32) * (bottom_up ? -1 : 1); + else if (video_format) + width /= video_format->bpp / 8; + height = (UINT32)frame_size; + + format->bmiHeader.biWidth = abs(width); + format->bmiHeader.biHeight = height * (bottom_up && width >= 0 ? -1 : 1); + + if (SUCCEEDED(MFCalculateImageSize(&am_type->subtype, abs(width), height, &image_size))) + format->bmiHeader.biSizeImage = image_size; + } + + if (user_size && FAILED(hr = IMFMediaType_GetBlob(media_type, &MF_MT_USER_DATA, + (BYTE *)(format + 1), user_size, NULL))) + return hr; + + am_type->formattype = FORMAT_VideoInfo; + am_type->subtype = get_am_subtype_for_mf_subtype(am_type->subtype); + } + else if (IsEqualGUID(&am_type->formattype, &FORMAT_VideoInfo2)) + { + FIXME("Not implemented!\n"); + am_type->formattype = GUID_NULL; + return E_NOTIMPL; + } + else + { + WARN("Unknown format %s\n", debugstr_mf_guid(&am_type->formattype)); + am_type->formattype = GUID_NULL; + } + + return S_OK; +} + /*********************************************************************** * MFInitAMMediaTypeFromMFMediaType (mfplat.@) */ HRESULT WINAPI MFInitAMMediaTypeFromMFMediaType(IMFMediaType *media_type, GUID format, AM_MEDIA_TYPE *am_type) { - FIXME("%p, %s, %p\n", media_type, debugstr_guid(&format), am_type); - return E_NOTIMPL; + UINT32 value, user_size; + HRESULT hr; + + TRACE("%p, %s, %p.\n", media_type, debugstr_mf_guid(&format), am_type); + + memset(am_type, 0, sizeof(*am_type)); + am_type->formattype = format; + + if (FAILED(hr = IMFMediaType_GetMajorType(media_type, &am_type->majortype)) + || FAILED(hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &am_type->subtype))) + goto done; + + if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value))) + am_type->bFixedSizeSamples = value; + if (SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &value))) + am_type->lSampleSize = value; + + if (FAILED(hr = IMFMediaType_GetBlob(media_type, &MF_MT_USER_DATA, NULL, 0, &user_size)) + && hr != E_NOT_SUFFICIENT_BUFFER) + user_size = 0; + + if (IsEqualGUID(&am_type->majortype, &MFMediaType_Audio)) + hr = init_am_media_type_audio_format(am_type, user_size, media_type); + else if (IsEqualGUID(&am_type->majortype, &MFMediaType_Video)) + hr = init_am_media_type_video_format(am_type, user_size, media_type); + else + { + FIXME("Not implemented!\n"); + hr = E_NOTIMPL; + } + +done: + if (FAILED(hr)) + { + CoTaskMemFree(am_type->pbFormat); + am_type->pbFormat = NULL; + am_type->cbFormat = 0; + } + + return hr; }
/*********************************************************************** diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 8379486d5bd..23de5d57158 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -7045,25 +7045,24 @@ static void test_MFInitAMMediaTypeFromMFMediaType(void) /* test basic media type attributes mapping and valid formats */
hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); - todo_wine ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); - todo_wine ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); - todo_wine ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = MFInitAMMediaTypeFromMFMediaType(media_type, FORMAT_VideoInfo, &am_type); - todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = MFInitAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (hr != S_OK) goto skip_tests; + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(IsEqualGUID(&am_type.majortype, &MFMediaType_Audio), "got %s.\n", debugstr_guid(&am_type.majortype)); ok(IsEqualGUID(&am_type.subtype, &MFAudioFormat_PCM), "got %s.\n", debugstr_guid(&am_type.subtype)); ok(IsEqualGUID(&am_type.formattype, &FORMAT_WaveFormatEx), "got %s.\n", debugstr_guid(&am_type.formattype)); @@ -7106,11 +7105,11 @@ static void test_MFInitAMMediaTypeFromMFMediaType(void) ok(am_type.cbFormat == sizeof(VIDEOINFOHEADER), "got %lu\n", am_type.cbFormat); CoTaskMemFree(am_type.pbFormat); hr = MFInitAMMediaTypeFromMFMediaType(media_type, FORMAT_VideoInfo2, &am_type); - ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(IsEqualGUID(&am_type.majortype, &MFMediaType_Video), "got %s.\n", debugstr_guid(&am_type.majortype)); - ok(IsEqualGUID(&am_type.subtype, &MEDIASUBTYPE_RGB32), "got %s.\n", debugstr_guid(&am_type.subtype)); - ok(IsEqualGUID(&am_type.formattype, &FORMAT_VideoInfo2), "got %s.\n", debugstr_guid(&am_type.formattype)); - ok(am_type.cbFormat == sizeof(VIDEOINFOHEADER2), "got %lu\n", am_type.cbFormat); + todo_wine ok(IsEqualGUID(&am_type.subtype, &MEDIASUBTYPE_RGB32), "got %s.\n", debugstr_guid(&am_type.subtype)); + todo_wine ok(IsEqualGUID(&am_type.formattype, &FORMAT_VideoInfo2), "got %s.\n", debugstr_guid(&am_type.formattype)); + todo_wine ok(am_type.cbFormat == sizeof(VIDEOINFOHEADER2), "got %lu\n", am_type.cbFormat); CoTaskMemFree(am_type.pbFormat); hr = MFInitAMMediaTypeFromMFMediaType(media_type, FORMAT_MFVideoFormat, &am_type); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -7522,7 +7521,6 @@ static void test_MFInitAMMediaTypeFromMFMediaType(void) CoTaskMemFree(am_type.pbFormat); IMFMediaType_DeleteAllItems(media_type);
-skip_tests: IMFMediaType_Release(media_type); }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/mediatype.c | 18 ++++++++++++++++-- dlls/mfplat/tests/mfplat.c | 10 ++++------ 2 files changed, 20 insertions(+), 8 deletions(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index 9e26b513250..2f5aad195d5 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -3159,8 +3159,22 @@ static void media_type_get_ratio(IMFMediaType *media_type, const GUID *attr, DWO */ HRESULT WINAPI MFCreateAMMediaTypeFromMFMediaType(IMFMediaType *media_type, GUID format, AM_MEDIA_TYPE **am_type) { - FIXME("%p, %s, %p stub!\n", media_type, debugstr_mf_guid(&format), am_type); - return E_NOTIMPL; + AM_MEDIA_TYPE *mt; + HRESULT hr; + + TRACE("%p, %s, %p.\n", media_type, debugstr_mf_guid(&format), am_type); + + *am_type = NULL; + if (!(mt = CoTaskMemAlloc(sizeof(*mt)))) + return E_OUTOFMEMORY; + if (FAILED(hr = MFInitAMMediaTypeFromMFMediaType(media_type, format, mt))) + { + CoTaskMemFree(mt); + return hr; + } + + *am_type = mt; + return hr; }
/*********************************************************************** diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 23de5d57158..a76b1471bc5 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -7534,23 +7534,22 @@ static void test_MFCreateAMMediaTypeFromMFMediaType(void) ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
hr = MFCreateAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); - todo_wine ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = MFCreateAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); - todo_wine ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = MFCreateAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); - todo_wine ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = MFCreateAMMediaTypeFromMFMediaType(media_type, GUID_NULL, &am_type); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (hr != S_OK) goto skip_tests; + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(IsEqualGUID(&am_type->majortype, &MFMediaType_Audio), "got %s.\n", debugstr_guid(&am_type->majortype)); ok(IsEqualGUID(&am_type->subtype, &MFAudioFormat_PCM), "got %s.\n", debugstr_guid(&am_type->subtype)); ok(IsEqualGUID(&am_type->formattype, &FORMAT_WaveFormatEx), "got %s.\n", debugstr_guid(&am_type->formattype)); @@ -7558,7 +7557,6 @@ static void test_MFCreateAMMediaTypeFromMFMediaType(void) CoTaskMemFree(am_type->pbFormat); CoTaskMemFree(am_type);
-skip_tests: IMFMediaType_Release(media_type); }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/mediatype.c | 48 +++++++++++++++++++++++++++----------- dlls/mfplat/tests/mfplat.c | 14 +++++------ 2 files changed, 40 insertions(+), 22 deletions(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index 2f5aad195d5..50f1ad3d9e0 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -616,16 +616,30 @@ static HRESULT WINAPI mediatype_IsEqual(IMFMediaType *iface, IMFMediaType *type,
static HRESULT WINAPI mediatype_GetRepresentation(IMFMediaType *iface, GUID guid, void **representation) { - FIXME("%p, %s, %p.\n", iface, debugstr_guid(&guid), representation); + TRACE("%p, %s, %p.\n", iface, debugstr_guid(&guid), representation);
- return E_NOTIMPL; + if (IsEqualGUID(&guid, &AM_MEDIA_TYPE_REPRESENTATION)) + return MFCreateAMMediaTypeFromMFMediaType(iface, GUID_NULL, (AM_MEDIA_TYPE **)representation); + + if (IsEqualGUID(&guid, &FORMAT_WaveFormatEx) + || IsEqualGUID(&guid, &FORMAT_VideoInfo) + || IsEqualGUID(&guid, &FORMAT_VideoInfo2) + || IsEqualGUID(&guid, &FORMAT_MFVideoFormat)) + return MFCreateAMMediaTypeFromMFMediaType(iface, guid, (AM_MEDIA_TYPE **)representation); + + FIXME("Format %s not implemented!\n", debugstr_guid(&guid)); + return MF_E_UNSUPPORTED_REPRESENTATION; }
static HRESULT WINAPI mediatype_FreeRepresentation(IMFMediaType *iface, GUID guid, void *representation) { - FIXME("%p, %s, %p.\n", iface, debugstr_guid(&guid), representation); + AM_MEDIA_TYPE *am_type = representation;
- return E_NOTIMPL; + TRACE("%p, %s, %p.\n", iface, debugstr_guid(&guid), representation); + + CoTaskMemFree(am_type->pbFormat); + CoTaskMemFree(am_type); + return S_OK; }
static const IMFMediaTypeVtbl mediatypevtbl = @@ -991,16 +1005,18 @@ static HRESULT WINAPI video_mediatype_IsEqual(IMFVideoMediaType *iface, IMFMedia
static HRESULT WINAPI video_mediatype_GetRepresentation(IMFVideoMediaType *iface, GUID guid, void **representation) { - FIXME("%p, %s, %p.\n", iface, debugstr_guid(&guid), representation); + TRACE("%p, %s, %p.\n", iface, debugstr_guid(&guid), representation);
- return E_NOTIMPL; + if (IsEqualGUID(&guid, &FORMAT_WaveFormatEx)) + return MF_E_UNSUPPORTED_REPRESENTATION; + + return mediatype_GetRepresentation((IMFMediaType *)iface, guid, representation); }
static HRESULT WINAPI video_mediatype_FreeRepresentation(IMFVideoMediaType *iface, GUID guid, void *representation) { - FIXME("%p, %s, %p.\n", iface, debugstr_guid(&guid), representation); - - return E_NOTIMPL; + TRACE("%p, %s, %p.\n", iface, debugstr_guid(&guid), representation); + return mediatype_FreeRepresentation((IMFMediaType *)iface, guid, representation); }
static const MFVIDEOFORMAT * WINAPI video_mediatype_GetVideoFormat(IMFVideoMediaType *iface) @@ -1392,16 +1408,20 @@ static HRESULT WINAPI audio_mediatype_IsEqual(IMFAudioMediaType *iface, IMFMedia
static HRESULT WINAPI audio_mediatype_GetRepresentation(IMFAudioMediaType *iface, GUID guid, void **representation) { - FIXME("%p, %s, %p.\n", iface, debugstr_guid(&guid), representation); + TRACE("%p, %s, %p.\n", iface, debugstr_guid(&guid), representation);
- return E_NOTIMPL; + if (IsEqualGUID(&guid, &FORMAT_VideoInfo) + || IsEqualGUID(&guid, &FORMAT_VideoInfo2) + || IsEqualGUID(&guid, &FORMAT_MFVideoFormat)) + return E_INVALIDARG; + + return mediatype_GetRepresentation((IMFMediaType *)iface, guid, representation); }
static HRESULT WINAPI audio_mediatype_FreeRepresentation(IMFAudioMediaType *iface, GUID guid, void *representation) { - FIXME("%p, %s, %p.\n", iface, debugstr_guid(&guid), representation); - - return E_NOTIMPL; + TRACE("%p, %s, %p.\n", iface, debugstr_guid(&guid), representation); + return mediatype_FreeRepresentation((IMFMediaType *)iface, guid, representation); }
static const WAVEFORMATEX * WINAPI audio_mediatype_GetAudioFormat(IMFAudioMediaType *iface) diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index a76b1471bc5..a3dfa89bca6 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -7571,27 +7571,26 @@ static void test_IMFMediaType_GetRepresentation(void) ok(hr == S_OK, "Failed to create media type, hr %#lx.\n", hr);
hr = IMFMediaType_GetRepresentation(media_type, GUID_NULL, (void **)&am_type); - todo_wine ok(hr == MF_E_UNSUPPORTED_REPRESENTATION, "Unexpected hr %#lx.\n", hr); + ok(hr == MF_E_UNSUPPORTED_REPRESENTATION, "Unexpected hr %#lx.\n", hr); hr = IMFMediaType_GetRepresentation(media_type, AM_MEDIA_TYPE_REPRESENTATION, (void **)&am_type); - todo_wine ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IMFMediaType_GetRepresentation(media_type, AM_MEDIA_TYPE_REPRESENTATION, (void **)&am_type); - todo_wine ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IMFMediaType_GetRepresentation(media_type, AM_MEDIA_TYPE_REPRESENTATION, (void **)&am_type); - todo_wine ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IMFMediaType_GetRepresentation(media_type, FORMAT_VideoInfo, (void **)&am_type); - todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); hr = IMFMediaType_GetRepresentation(media_type, AM_MEDIA_TYPE_REPRESENTATION, (void **)&am_type); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (hr != S_OK) goto skip_tests; + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(IsEqualGUID(&am_type->majortype, &MFMediaType_Audio), "got %s.\n", debugstr_guid(&am_type->majortype)); ok(IsEqualGUID(&am_type->subtype, &MFAudioFormat_PCM), "got %s.\n", debugstr_guid(&am_type->subtype)); ok(IsEqualGUID(&am_type->formattype, &FORMAT_WaveFormatEx), "got %s.\n", debugstr_guid(&am_type->formattype)); @@ -7631,7 +7630,6 @@ static void test_IMFMediaType_GetRepresentation(void) hr = IMFMediaType_FreeRepresentation(media_type, AM_MEDIA_TYPE_REPRESENTATION, am_type); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
-skip_tests: IMFMediaType_Release(media_type); }
On Mon Nov 20 11:00:13 2023 +0000, Rémi Bernon wrote:
changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/4439/diffs?diff_id=84500&start_sha=3417bb69a636e815dc7e226e3bd5978226bb37f9#856f958c3f51ca87a2b3b1d1a0efd2130d1c6c4c_7596_7598)
Indeed, done.
On Mon Nov 20 11:01:35 2023 +0000, Nikolay Sivov wrote:
Let's include that in the following if () sequence, merging GUID_NULL with VideoInfo.
Done.
On Mon Nov 20 11:01:36 2023 +0000, Nikolay Sivov wrote:
Do those accept audio formats actually? Same for audio_mediatype_* vs video formats.
`MFInitAMMediaTypeFromMFMediaType` already doesn't accept them if the major type don't match the formats. Anyway, I added a couple of tests and returned the appropriate errors.
On Mon Nov 20 10:22:21 2023 +0000, Rémi Bernon wrote:
I'm not sure what you mean? Only a few RGB format GUID have a different value between MEDIASUBTYPE and MFVideoFormat. The code was converting some YUV formats unnecessarily, and missing other formats that don't need conversion (when they share `MFVideoFormat_Base`). This is also to make sure the `get_mf_subtype_for_am_subtype` conversion matches the later introduced `get_am_subtype_for_mf_subtype`.
I don't think adding checks based on the way those GUIDs are declared makes it more readable.
On Mon Nov 20 16:02:20 2023 +0000, Nikolay Sivov wrote:
I don't think adding checks based on the way those GUIDs are declared makes it more readable.
So simply return subtype instead?
On Mon Nov 20 16:35:13 2023 +0000, Rémi Bernon wrote:
So simply return subtype instead?
Fwiw there are more RGB MEDIASUBTYPEs which may need mapping and that I haven't included there because I didn't find the corresponding MFVideoFormat GUID. The check was also there to catch any of these if they were used.
On Mon Nov 20 16:37:25 2023 +0000, Rémi Bernon wrote:
Fwiw there are more RGB MEDIASUBTYPEs which may need mapping and that I haven't included there because I didn't find the corresponding MFVideoFormat GUID. The check was also there to catch any of these if they were used.
Return 'subtype' or corresponding MFVideoFormat name, but make it clear what are those returned for. Is there a lot of them, is that a concern?