-- v5: 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 | 52 ++++++++++++++++++++++++++++++++++++++ include/mfapi.h | 2 ++ 4 files changed, 81 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..2e340062abd 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -8524,6 +8524,57 @@ 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); + memset(&guid, 0xcd, sizeof(guid)); + hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &guid); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + 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); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine + 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 +11849,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;
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=144250
Your paranoid android.
=== debian11 (32 bit report) ===
mfplat: Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00415642).
Report validation errors: mfplat:mfplat prints too much data (45844 bytes)
=== debian11 (32 bit ar:MA report) ===
mfplat: Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00415642).
=== debian11 (32 bit de report) ===
mfplat: Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00415642).
=== debian11 (32 bit fr report) ===
mfplat: Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00415642).
=== debian11 (32 bit he:IL report) ===
mfplat: Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00415642).
=== debian11 (32 bit hi:IN report) ===
mfplat: Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00415642).
=== debian11 (32 bit ja:JP report) ===
mfplat: Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00415642).
=== debian11 (32 bit zh:CN report) ===
mfplat: Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x00415642).
=== debian11b (32 bit WoW report) ===
Report validation errors: mfplat:mfplat crashed (c0000005) mfplat:mfplat prints too much data (44716 bytes)
=== debian11b (64 bit WoW report) ===
Report validation errors: mfplat:mfplat crashed (c0000005)
On Wed Mar 20 21:09:00 2024 +0000, Nikolay Sivov wrote:
Let's add a fixme for unrecognized representation guids. A simple test would be helpful too, maybe we should simply fail, and that will remove some branching as well.
Added tests for this.