-- v6: mfplat/mediatype: Use MFCreateWaveFormatExFromMFMediaType in init_am_media_type_audio_format. mfplat/mediatype: Implement MFCreateMediaTypeFromRepresentation. mfplat/mediatype: Force WAVEFORMATEXTENSIBLE in MFCreateWaveFormatExFromMFMediaType in some cases. mfplat/mediatype: Support audio major type in MFInitMediaTypeFromAMMediaType. mfplat/mediatype: Check format pointers and sizes in MFInitMediaTypeFromAMMediaType. mfplat/tests: Check how AAC attributes are copied from user data. mfplat/tests: Test initializing mediatype from AAC WAVEFORMATEXTENSIBLE. mfplat/tests: Add some broken results for Win7.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/tests/mfplat.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 97f5dafef86..1c45014f32f 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -10868,7 +10868,9 @@ static void test_MFInitMediaTypeFromVideoInfoHeader2(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value32); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - ok(value32 == MFVideoInterlace_MixedInterlaceOrProgressive, "Unexpected value %#x.\n", value32); + ok(value32 == MFVideoInterlace_MixedInterlaceOrProgressive + || broken(value32 == MFVideoInterlace_FieldInterleavedLowerFirst) /* Win7 */, + "Unexpected value %#x.\n", value32);
vih.dwPictAspectRatioX = 123; hr = MFInitMediaTypeFromVideoInfoHeader2(media_type, &vih, sizeof(vih), &GUID_NULL);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/tests/mfplat.c | 71 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 69 insertions(+), 2 deletions(-)
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 1c45014f32f..beb3f83432f 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -6998,6 +6998,7 @@ static void test_MFInitMediaTypeFromWaveFormatEx(void) HEAACWAVEFORMAT aacformat; IMFMediaType *mediatype; unsigned int i, size; + WAVEFORMATEX *wfx; UINT32 value; HRESULT hr;
@@ -7087,6 +7088,15 @@ static void test_MFInitMediaTypeFromWaveFormatEx(void) ok(size == aacformat.wfInfo.wfx.cbSize, "Unexpected size %u.\n", size); ok(!memcmp(buff, (WAVEFORMATEX *)&aacformat + 1, size), "Unexpected user data.\n");
+ /* check that we get an HEAACWAVEFORMAT by default */ + hr = MFCreateWaveFormatExFromMFMediaType(mediatype, (WAVEFORMATEX **)&wfx, &size, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(wfx->wFormatTag == WAVE_FORMAT_MPEG_HEAAC, "got wFormatTag %#x\n", wfx->wFormatTag); + ok(wfx->cbSize == sizeof(HEAACWAVEFORMAT) - sizeof(WAVEFORMATEX), "got cbSize %u\n", wfx->cbSize); + ok(!memcmp(wfx + 1, &aacformat.wfInfo.wfx + 1, aacformat.wfInfo.wfx.cbSize), "Unexpected user data.\n"); + CoTaskMemFree(wfx); + + /* MFWaveFormatExConvertFlag_ForceExtensible can force a WAVEFORMATEXTENSIBLE */ hr = MFCreateWaveFormatExFromMFMediaType(mediatype, (WAVEFORMATEX **)&format, &size, MFWaveFormatExConvertFlag_ForceExtensible); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(format->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "got wFormatTag %#x\n", format->Format.wFormatTag); @@ -7098,6 +7108,62 @@ static void test_MFInitMediaTypeFromWaveFormatEx(void) ok(!memcmp(format + 1, &aacformat.wfInfo.wfx + 1, aacformat.wfInfo.wfx.cbSize), "Unexpected user data.\n"); CoTaskMemFree(format);
+ /* adding more channels has no immediate effect */ + hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_AUDIO_NUM_CHANNELS, 6); + ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr); + hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_AUDIO_CHANNEL_MASK, 63); + ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr); + hr = MFCreateWaveFormatExFromMFMediaType(mediatype, (WAVEFORMATEX **)&wfx, &size, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(wfx->wFormatTag == WAVE_FORMAT_MPEG_HEAAC, "got wFormatTag %#x\n", wfx->wFormatTag); + ok(wfx->cbSize == sizeof(HEAACWAVEFORMAT) - sizeof(WAVEFORMATEX), "got cbSize %u\n", wfx->cbSize); + ok(!memcmp(wfx + 1, &aacformat.wfInfo.wfx + 1, aacformat.wfInfo.wfx.cbSize), "Unexpected user data.\n"); + CoTaskMemFree(wfx); + + /* but adding MF_MT_AUDIO_SAMPLES_PER_BLOCK as well forces the WAVEFORMATEXTENSIBLE format */ + hr = IMFMediaType_SetUINT32(mediatype, &MF_MT_AUDIO_SAMPLES_PER_BLOCK, 4); + ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr); + hr = MFCreateWaveFormatExFromMFMediaType(mediatype, (WAVEFORMATEX **)&format, &size, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(format->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "got wFormatTag %#x\n", format->Format.wFormatTag); + todo_wine + ok(format->Format.cbSize == aacformat.wfInfo.wfx.cbSize + sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX), + "got cbSize %u\n", format->Format.cbSize); + todo_wine + ok(IsEqualGUID(&format->SubFormat, &MFAudioFormat_AAC), "got SubFormat %s\n", debugstr_guid(&format->SubFormat)); + todo_wine + ok(format->dwChannelMask == 63, "got dwChannelMask %#lx\n", format->dwChannelMask); + todo_wine + ok(format->Samples.wSamplesPerBlock == 4, "got wSamplesPerBlock %u\n", format->Samples.wSamplesPerBlock); + todo_wine + ok(!memcmp(format + 1, &aacformat.wfInfo.wfx + 1, aacformat.wfInfo.wfx.cbSize), "Unexpected user data.\n"); + + /* test initializing media type from an WAVE_FORMAT_EXTENSIBLE AAC format */ + IMFMediaType_DeleteAllItems(mediatype); + hr = MFInitMediaTypeFromWaveFormatEx(mediatype, (WAVEFORMATEX *)format, sizeof(WAVEFORMATEX) + format->Format.cbSize); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + CoTaskMemFree(format); + + value = 0xdeadbeef; + hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, &value); + todo_wine + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Failed to get attribute, hr %#lx.\n", hr); + todo_wine + ok(value == 0xdeadbeef, "Unexpected AAC_AUDIO_PROFILE_LEVEL_INDICATION %u.\n", value); + value = 0xdeadbeef; + hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AAC_PAYLOAD_TYPE, &value); + todo_wine + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Failed to get attribute, hr %#lx.\n", hr); + todo_wine + ok(value == 0xdeadbeef, "Unexpected AAC_PAYLOAD_TYPE %u.\n", value); + + hr = IMFMediaType_GetBlob(mediatype, &MF_MT_USER_DATA, buff, sizeof(buff), &size); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(size == aacformat.wfInfo.wfx.cbSize, "Unexpected size %u.\n", size); + ok(!memcmp(buff, (WAVEFORMATEX *)&aacformat + 1, size), "Unexpected user data.\n"); + + /* test with invalid format size */ aacformat.wfInfo.wfx.cbSize = 1; hr = IMFMediaType_SetBlob(mediatype, &MF_MT_USER_DATA, buff, aacformat.wfInfo.wfx.cbSize); @@ -7108,8 +7174,9 @@ static void test_MFInitMediaTypeFromWaveFormatEx(void) ok(format->Format.cbSize == aacformat.wfInfo.wfx.cbSize + sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX), "got cbSize %u\n", format->Format.cbSize); ok(IsEqualGUID(&format->SubFormat, &MFAudioFormat_AAC), "got SubFormat %s\n", debugstr_guid(&format->SubFormat)); - ok(format->dwChannelMask == 3, "got dwChannelMask %#lx\n", format->dwChannelMask); - ok(format->Samples.wSamplesPerBlock == 0, "got wSamplesPerBlock %u\n", format->Samples.wSamplesPerBlock); + ok(format->dwChannelMask == 63, "got dwChannelMask %#lx\n", format->dwChannelMask); + todo_wine + ok(format->Samples.wSamplesPerBlock == 4, "got wSamplesPerBlock %u\n", format->Samples.wSamplesPerBlock); ok(!memcmp(format + 1, &aacformat.wfInfo.wfx + 1, aacformat.wfInfo.wfx.cbSize), "Unexpected user data.\n"); CoTaskMemFree(format);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/tests/mfplat.c | 88 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 88 insertions(+)
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index beb3f83432f..e4989e4bcea 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -74,6 +74,7 @@ DEFINE_MEDIATYPE_GUID(MFVideoFormat_ARGB1555, D3DFMT_A1R5G5B5); DEFINE_MEDIATYPE_GUID(MFVideoFormat_ARGB4444, D3DFMT_A4R4G4B4); /* SDK MFVideoFormat_A2R10G10B10 uses D3DFMT_A2B10G10R10, let's name it the other way */ DEFINE_MEDIATYPE_GUID(MFVideoFormat_A2B10G10R10, D3DFMT_A2R10G10B10); +DEFINE_MEDIATYPE_GUID(MFAudioFormat_RAW_AAC,WAVE_FORMAT_RAW_AAC1);
DEFINE_MEDIATYPE_GUID(MEDIASUBTYPE_h264,MAKEFOURCC('h','2','6','4')); DEFINE_MEDIATYPE_GUID(MEDIASUBTYPE_MP3,WAVE_FORMAT_MPEGLAYER3); @@ -6991,6 +6992,15 @@ static void test_MFInitMediaTypeFromWaveFormatEx(void) { WAVE_FORMAT_WMASPDIF }, };
+ static const BYTE aac_codec_data[] = + { + 0x12, 0x00, + 0x34, 0x00, + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x12, 0x08, + }; UINT8 buff[1024]; WAVEFORMATEXTENSIBLE waveformatext; MPEGLAYER3WAVEFORMAT mp3format; @@ -7180,6 +7190,84 @@ static void test_MFInitMediaTypeFromWaveFormatEx(void) ok(!memcmp(format + 1, &aacformat.wfInfo.wfx + 1, aacformat.wfInfo.wfx.cbSize), "Unexpected user data.\n"); CoTaskMemFree(format);
+ IMFMediaType_DeleteAllItems(mediatype); + + + /* check that HEAACWAVEFORMAT extra fields are copied directly from MF_MT_USER_DATA */ + aacformat.wfInfo.wfx.cbSize = sizeof(aacformat) - sizeof(WAVEFORMATEX); + hr = MFInitMediaTypeFromWaveFormatEx(mediatype, (WAVEFORMATEX *)&aacformat, sizeof(aacformat)); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaType_DeleteItem(mediatype, &MF_MT_USER_DATA); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFCreateWaveFormatExFromMFMediaType(mediatype, (WAVEFORMATEX **)&wfx, &size, 0); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (hr == S_OK) + { + ok(wfx->wFormatTag == WAVE_FORMAT_MPEG_HEAAC, "got wFormatTag %#x\n", wfx->wFormatTag); + ok(wfx->cbSize == 0, "got cbSize %u\n", wfx->cbSize); + CoTaskMemFree(wfx); + } + + hr = IMFMediaType_DeleteItem(mediatype, &MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_DeleteItem(mediatype, &MF_MT_AAC_PAYLOAD_TYPE); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetBlob(mediatype, &MF_MT_USER_DATA, aac_codec_data, sizeof(aac_codec_data)); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = MFCreateWaveFormatExFromMFMediaType(mediatype, (WAVEFORMATEX **)&wfx, &size, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(wfx->wFormatTag == WAVE_FORMAT_MPEG_HEAAC, "got wFormatTag %#x\n", wfx->wFormatTag); + ok(wfx->cbSize == sizeof(aac_codec_data), "got cbSize %u\n", wfx->cbSize); + memcpy(&aacformat, wfx, sizeof(aacformat)); + ok(aacformat.wfInfo.wPayloadType == 0x12, "got %u\n", aacformat.wfInfo.wPayloadType); + ok(aacformat.wfInfo.wAudioProfileLevelIndication == 0x34, "got %u\n", aacformat.wfInfo.wAudioProfileLevelIndication); + + hr = MFInitMediaTypeFromWaveFormatEx(mediatype, wfx, sizeof(*wfx) + wfx->cbSize); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + value = 0xdeadbeef; + hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AAC_PAYLOAD_TYPE, &value); + ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr); + ok(value == 0x12, "Unexpected AAC_PAYLOAD_TYPE %u.\n", value); + value = 0xdeadbeef; + hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, &value); + ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr); + ok(value == 0x34, "Unexpected AAC_AUDIO_PROFILE_LEVEL_INDICATION %u.\n", value); + + CoTaskMemFree(wfx); + + + /* check that RAW AAC doesn't have MF_MT_AAC_* attributes */ + aacformat.wfInfo.wfx.cbSize = sizeof(aacformat) - sizeof(WAVEFORMATEX); + hr = MFInitMediaTypeFromWaveFormatEx(mediatype, (WAVEFORMATEX *)&aacformat, sizeof(aacformat)); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetGUID(mediatype, &MF_MT_SUBTYPE, &MFAudioFormat_RAW_AAC); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaType_DeleteItem(mediatype, &MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_DeleteItem(mediatype, &MF_MT_AAC_PAYLOAD_TYPE); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_SetBlob(mediatype, &MF_MT_USER_DATA, aac_codec_data, sizeof(aac_codec_data)); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = MFCreateWaveFormatExFromMFMediaType(mediatype, (WAVEFORMATEX **)&wfx, &size, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(wfx->wFormatTag == WAVE_FORMAT_RAW_AAC1, "got wFormatTag %#x\n", wfx->wFormatTag); + ok(wfx->cbSize == sizeof(aac_codec_data), "got cbSize %u\n", wfx->cbSize); + + hr = MFInitMediaTypeFromWaveFormatEx(mediatype, wfx, sizeof(*wfx) + wfx->cbSize); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AAC_PAYLOAD_TYPE, &value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Failed to get attribute, hr %#lx.\n", hr); + hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, &value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Failed to get attribute, hr %#lx.\n", hr); + + CoTaskMemFree(wfx); + + IMFMediaType_Release(mediatype); }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/mediatype.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index e07cc2339c1..d8f39678278 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -4270,13 +4270,17 @@ HRESULT WINAPI MFInitMediaTypeFromAMMediaType(IMFMediaType *media_type, const AM { const GUID *subtype = get_mf_subtype_for_am_subtype(&am_type->subtype);
- if (IsEqualGUID(&am_type->formattype, &FORMAT_VideoInfo)) + if (am_type->cbFormat && !am_type->pbFormat) + hr = E_INVALIDARG; + else if (IsEqualGUID(&am_type->formattype, &FORMAT_VideoInfo) + && am_type->cbFormat >= sizeof(VIDEOINFOHEADER)) hr = MFInitMediaTypeFromVideoInfoHeader(media_type, (VIDEOINFOHEADER *)am_type->pbFormat, am_type->cbFormat, subtype); - else if (IsEqualGUID(&am_type->formattype, &FORMAT_VideoInfo2)) + else if (IsEqualGUID(&am_type->formattype, &FORMAT_VideoInfo2) + && am_type->cbFormat >= sizeof(VIDEOINFOHEADER2)) hr = MFInitMediaTypeFromVideoInfoHeader2(media_type, (VIDEOINFOHEADER2 *)am_type->pbFormat, am_type->cbFormat, subtype); else { - FIXME("Unsupported format type %s.\n", debugstr_guid(&am_type->formattype)); + FIXME("Unsupported format type %s / size %ld.\n", debugstr_guid(&am_type->formattype), am_type->cbFormat); return E_NOTIMPL; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/mediatype.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index d8f39678278..b5ed16e41f1 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -4283,13 +4283,19 @@ HRESULT WINAPI MFInitMediaTypeFromAMMediaType(IMFMediaType *media_type, const AM FIXME("Unsupported format type %s / size %ld.\n", debugstr_guid(&am_type->formattype), am_type->cbFormat); return E_NOTIMPL; } - - if (!am_type->bTemporalCompression && FAILED(IMFMediaType_GetItem(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, NULL))) - mediatype_set_uint32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, 1, &hr); - if (am_type->bFixedSizeSamples && FAILED(IMFMediaType_GetItem(media_type, &MF_MT_FIXED_SIZE_SAMPLES, NULL))) - mediatype_set_uint32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, 1, &hr); - if (am_type->lSampleSize && FAILED(IMFMediaType_GetItem(media_type, &MF_MT_SAMPLE_SIZE, NULL))) - mediatype_set_uint32(media_type, &MF_MT_SAMPLE_SIZE, am_type->lSampleSize, &hr); + } + else if (IsEqualGUID(&am_type->majortype, &MEDIATYPE_Audio)) + { + if (am_type->cbFormat && !am_type->pbFormat) + hr = E_INVALIDARG; + else if (IsEqualGUID(&am_type->formattype, &FORMAT_WaveFormatEx) + && am_type->cbFormat >= sizeof(WAVEFORMATEX)) + hr = MFInitMediaTypeFromWaveFormatEx(media_type, (WAVEFORMATEX *)am_type->pbFormat, am_type->cbFormat); + else + { + FIXME("Unsupported format type %s / size %ld.\n", debugstr_guid(&am_type->formattype), am_type->cbFormat); + return E_NOTIMPL; + } } else { @@ -4297,5 +4303,12 @@ HRESULT WINAPI MFInitMediaTypeFromAMMediaType(IMFMediaType *media_type, const AM return E_NOTIMPL; }
+ if (!am_type->bTemporalCompression && FAILED(IMFMediaType_GetItem(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, NULL))) + mediatype_set_uint32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, 1, &hr); + if (am_type->bFixedSizeSamples && FAILED(IMFMediaType_GetItem(media_type, &MF_MT_FIXED_SIZE_SAMPLES, NULL))) + mediatype_set_uint32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, 1, &hr); + if (am_type->lSampleSize && FAILED(IMFMediaType_GetItem(media_type, &MF_MT_SAMPLE_SIZE, NULL))) + mediatype_set_uint32(media_type, &MF_MT_SAMPLE_SIZE, am_type->lSampleSize, &hr); + return hr; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/mediatype.c | 28 +++++++++++++++++++++++++--- dlls/mfplat/tests/mfplat.c | 6 ------ dlls/winegstreamer/aac_decoder.c | 1 + 3 files changed, 26 insertions(+), 9 deletions(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index b5ed16e41f1..9c4b9877e02 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -2980,7 +2980,7 @@ HRESULT WINAPI MFCreateWaveFormatExFromMFMediaType(IMFMediaType *mediatype, WAVE { UINT32 value, extra_size = 0, user_size; WAVEFORMATEX *format; - GUID major, subtype; + GUID major, subtype, basetype = MFAudioFormat_Base; void *user_data; HRESULT hr;
@@ -3002,6 +3002,19 @@ HRESULT WINAPI MFCreateWaveFormatExFromMFMediaType(IMFMediaType *mediatype, WAVE user_size = 0; }
+ if (SUCCEEDED(IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_NUM_CHANNELS, &value)) && value > 2 + && SUCCEEDED(IMFMediaType_GetItem(mediatype, &MF_MT_AUDIO_CHANNEL_MASK, NULL))) + { + if (SUCCEEDED(IMFMediaType_GetItem(mediatype, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, NULL))) + flags = MFWaveFormatExConvertFlag_ForceExtensible; + if (SUCCEEDED(IMFMediaType_GetItem(mediatype, &MF_MT_AUDIO_SAMPLES_PER_BLOCK, NULL))) + flags = MFWaveFormatExConvertFlag_ForceExtensible; + } + + basetype.Data1 = subtype.Data1; + if (subtype.Data1 >> 16 || !IsEqualGUID(&subtype, &basetype)) + flags = MFWaveFormatExConvertFlag_ForceExtensible; + if (flags == MFWaveFormatExConvertFlag_ForceExtensible) extra_size = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(*format);
@@ -3034,6 +3047,8 @@ HRESULT WINAPI MFCreateWaveFormatExFromMFMediaType(IMFMediaType *mediatype, WAVE user_data = format_ext + 1;
if (SUCCEEDED(IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, &value))) + format_ext->Samples.wValidBitsPerSample = value; + if (SUCCEEDED(IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_SAMPLES_PER_BLOCK, &value))) format_ext->Samples.wSamplesPerBlock = value;
if (SUCCEEDED(IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_CHANNEL_MASK, &value))) @@ -3080,6 +3095,8 @@ static void mediatype_set_blob(IMFMediaType *mediatype, const GUID *attr, const HRESULT WINAPI MFInitMediaTypeFromWaveFormatEx(IMFMediaType *mediatype, const WAVEFORMATEX *format, UINT32 size) { const WAVEFORMATEXTENSIBLE *wfex = (const WAVEFORMATEXTENSIBLE *)format; + const void *user_data; + int user_data_size; GUID subtype; HRESULT hr;
@@ -3104,6 +3121,9 @@ HRESULT WINAPI MFInitMediaTypeFromWaveFormatEx(IMFMediaType *mediatype, const WA
if (format->wBitsPerSample && wfex->Samples.wValidBitsPerSample) mediatype_set_uint32(mediatype, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, wfex->Samples.wValidBitsPerSample, &hr); + + user_data_size = format->cbSize - sizeof(WAVEFORMATEXTENSIBLE) + sizeof(WAVEFORMATEX); + user_data = wfex + 1; } else { @@ -3111,6 +3131,8 @@ HRESULT WINAPI MFInitMediaTypeFromWaveFormatEx(IMFMediaType *mediatype, const WA subtype.Data1 = format->wFormatTag;
mediatype_set_uint32(mediatype, &MF_MT_AUDIO_PREFER_WAVEFORMATEX, 1, &hr); + user_data_size = format->cbSize; + user_data = format + 1; } mediatype_set_guid(mediatype, &MF_MT_SUBTYPE, &subtype, &hr);
@@ -3144,8 +3166,8 @@ HRESULT WINAPI MFInitMediaTypeFromWaveFormatEx(IMFMediaType *mediatype, const WA mediatype_set_uint32(mediatype, &MF_MT_AAC_PAYLOAD_TYPE, info->wPayloadType, &hr); }
- if (format->cbSize && format->wFormatTag != WAVE_FORMAT_EXTENSIBLE) - mediatype_set_blob(mediatype, &MF_MT_USER_DATA, (const UINT8 *)(format + 1), format->cbSize, &hr); + if (user_data_size > 0) + mediatype_set_blob(mediatype, &MF_MT_USER_DATA, user_data, user_data_size, &hr);
return hr; } diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index e4989e4bcea..0cfe296b260 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -7135,18 +7135,12 @@ static void test_MFInitMediaTypeFromWaveFormatEx(void) ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr); hr = MFCreateWaveFormatExFromMFMediaType(mediatype, (WAVEFORMATEX **)&format, &size, 0); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - todo_wine ok(format->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "got wFormatTag %#x\n", format->Format.wFormatTag); - todo_wine ok(format->Format.cbSize == aacformat.wfInfo.wfx.cbSize + sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX), "got cbSize %u\n", format->Format.cbSize); - todo_wine ok(IsEqualGUID(&format->SubFormat, &MFAudioFormat_AAC), "got SubFormat %s\n", debugstr_guid(&format->SubFormat)); - todo_wine ok(format->dwChannelMask == 63, "got dwChannelMask %#lx\n", format->dwChannelMask); - todo_wine ok(format->Samples.wSamplesPerBlock == 4, "got wSamplesPerBlock %u\n", format->Samples.wSamplesPerBlock); - todo_wine ok(!memcmp(format + 1, &aacformat.wfInfo.wfx + 1, aacformat.wfInfo.wfx.cbSize), "Unexpected user data.\n");
/* test initializing media type from an WAVE_FORMAT_EXTENSIBLE AAC format */ diff --git a/dlls/winegstreamer/aac_decoder.c b/dlls/winegstreamer/aac_decoder.c index c0bc57f278e..5844de33ceb 100644 --- a/dlls/winegstreamer/aac_decoder.c +++ b/dlls/winegstreamer/aac_decoder.c @@ -292,6 +292,7 @@ static HRESULT WINAPI transform_GetOutputAvailableType(IMFTransform *iface, DWOR wfx.SubFormat = MFAudioFormat_Base; wfx.SubFormat.Data1 = wfx.Format.wFormatTag; wfx.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; + wfx.Format.cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); wfx.dwChannelMask = default_channel_mask[wfx.Format.nChannels]; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/mediatype.c | 26 +++++++++++++++++++ dlls/mfplat/mfplat.spec | 2 +- dlls/mfplat/tests/mfplat.c | 51 ++++++++++++++++++++++++++++++++++++++ include/mfapi.h | 2 ++ 4 files changed, 80 insertions(+), 1 deletion(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index 9c4b9877e02..f584e1aae26 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -4334,3 +4334,29 @@ HRESULT WINAPI MFInitMediaTypeFromAMMediaType(IMFMediaType *media_type, const AM
return hr; } + +/*********************************************************************** + * MFCreateMediaTypeFromRepresentation (mfplat.@) + */ +HRESULT WINAPI MFCreateMediaTypeFromRepresentation(GUID guid_representation, void *representation, + IMFMediaType **media_type) +{ + HRESULT hr; + + TRACE("%s, %p, %p\n", debugstr_guid(&guid_representation), representation, media_type); + + if (!IsEqualGUID(&guid_representation, &AM_MEDIA_TYPE_REPRESENTATION)) + return MF_E_UNSUPPORTED_REPRESENTATION; + if (!representation || !media_type) + return E_INVALIDARG; + + if (FAILED(hr = MFCreateMediaType(media_type))) + return hr; + if (FAILED(hr = MFInitMediaTypeFromAMMediaType(*media_type, representation))) + { + IMFMediaType_Release(*media_type); + *media_type = NULL; + } + + return hr; +} diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec index d8a6eb5ce83..57db3cdf9f6 100644 --- a/dlls/mfplat/mfplat.spec +++ b/dlls/mfplat/mfplat.spec @@ -59,7 +59,7 @@ @ stub MFCreateMediaBufferWrapper @ stdcall MFCreateMediaEvent(long ptr long ptr ptr) @ stdcall MFCreateMediaType(ptr) -@ stub MFCreateMediaTypeFromRepresentation +@ stdcall MFCreateMediaTypeFromRepresentation(int128 ptr ptr) @ stdcall MFCreateMemoryBuffer(long ptr) @ stub MFCreateMemoryStream @ stdcall MFCreatePathFromURL(wstr ptr) diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 0cfe296b260..2ff78a2b05a 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -8524,6 +8524,56 @@ static void test_IMFMediaType_GetRepresentation(void) IMFMediaType_Release(media_type); }
+static void test_MFCreateMediaTypeFromRepresentation(void) +{ + IMFMediaType *media_type; + AM_MEDIA_TYPE amt = {0}; + WAVEFORMATEX wfx = {0}; + HRESULT hr; + GUID guid; + + hr = MFCreateMediaTypeFromRepresentation(GUID_NULL, &amt, &media_type); + ok(hr == MF_E_UNSUPPORTED_REPRESENTATION, "Unexpected hr %#lx.\n", hr); + hr = MFCreateMediaTypeFromRepresentation(AM_MEDIA_TYPE_REPRESENTATION, NULL, &media_type); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + hr = MFCreateMediaTypeFromRepresentation(AM_MEDIA_TYPE_REPRESENTATION, &amt, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + hr = MFCreateMediaTypeFromRepresentation(AM_MEDIA_TYPE_REPRESENTATION, &amt, &media_type); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (hr == S_OK) + { + memset(&guid, 0xcd, sizeof(guid)); + hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&guid, &GUID_NULL), "got %s.\n", debugstr_guid(&guid)); + memset(&guid, 0xcd, sizeof(guid)); + hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&guid, &GUID_NULL), "got %s.\n", debugstr_guid(&guid)); + IMFMediaType_Release(media_type); + } + + amt.formattype = FORMAT_WaveFormatEx; + amt.majortype = MFMediaType_Audio; + amt.subtype = MFAudioFormat_PCM; + amt.pbFormat = (BYTE *)&wfx; + amt.cbFormat = sizeof(wfx); + hr = MFCreateMediaTypeFromRepresentation(AM_MEDIA_TYPE_REPRESENTATION, &amt, &media_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + memset(&guid, 0xcd, sizeof(guid)); + hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(IsEqualGUID(&guid, &MFMediaType_Audio), "got %s.\n", debugstr_guid(&guid)); + memset(&guid, 0xcd, sizeof(guid)); + hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + ok(IsEqualGUID(&guid, &MFAudioFormat_PCM), "got %s.\n", debugstr_guid(&guid)); + IMFMediaType_Release(media_type); +} + static void test_MFCreateDXSurfaceBuffer(void) { IDirect3DSurface9 *backbuffer = NULL, *surface; @@ -11798,6 +11848,7 @@ START_TEST(mfplat) test_MFCreateAMMediaTypeFromMFMediaType(); test_MFInitMediaTypeFromMFVideoFormat(); test_IMFMediaType_GetRepresentation(); + test_MFCreateMediaTypeFromRepresentation(); test_MFCreateDXSurfaceBuffer(); test_MFCreateTrackedSample(); test_MFFrameRateToAverageTimePerFrame(); diff --git a/include/mfapi.h b/include/mfapi.h index f986edd0d5a..0a9f7c6f415 100644 --- a/include/mfapi.h +++ b/include/mfapi.h @@ -549,6 +549,8 @@ HRESULT WINAPI MFCreateMediaEvent(MediaEventType type, REFGUID extended_type, HR 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 MFCreateMediaTypeFromRepresentation(GUID guid_representation, void *representation, + IMFMediaType **media_type); HRESULT WINAPI MFCreateSample(IMFSample **sample); HRESULT WINAPI MFCreateTempFile(MF_FILE_ACCESSMODE accessmode, MF_FILE_OPENMODE openmode, MF_FILE_FLAGS flags, IMFByteStream **bytestream);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/mediatype.c | 60 +++++------------------------------------ 1 file changed, 6 insertions(+), 54 deletions(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index f584e1aae26..df1334d51ff 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -3992,7 +3992,7 @@ HRESULT WINAPI MFInitMediaTypeFromVideoInfoHeader(IMFMediaType *media_type, cons
static HRESULT init_am_media_type_audio_format(AM_MEDIA_TYPE *am_type, UINT32 user_size, IMFMediaType *media_type) { - UINT32 num_channels, value; + UINT32 num_channels; HRESULT hr;
if (IsEqualGUID(&am_type->formattype, &FORMAT_VideoInfo) @@ -4003,7 +4003,7 @@ static HRESULT init_am_media_type_audio_format(AM_MEDIA_TYPE *am_type, UINT32 us if (IsEqualGUID(&am_type->formattype, &FORMAT_WaveFormatEx) || IsEqualGUID(&am_type->formattype, &GUID_NULL)) { - WAVEFORMATEX *format; + UINT32 flags = 0;
if (FAILED(IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_NUM_CHANNELS, &num_channels))) num_channels = 0; @@ -4012,59 +4012,11 @@ static HRESULT init_am_media_type_audio_format(AM_MEDIA_TYPE *am_type, UINT32 us || 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; - } + flags = MFWaveFormatExConvertFlag_ForceExtensible;
- 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; + if (FAILED(hr = MFCreateWaveFormatExFromMFMediaType(media_type, (WAVEFORMATEX **)&am_type->pbFormat, + (UINT32 *)&am_type->cbFormat, flags))) + return hr;
am_type->subtype = get_am_subtype_for_mf_subtype(am_type->subtype); am_type->formattype = FORMAT_WaveFormatEx;
v6: Avoid a crash in the tests when we run into the todo_wine.
This merge request was approved by Nikolay Sivov.