This will make it possible to move some specific behavior out of the AAC decoder transform, and ultimately make it easier to have a generic audio decoder.
-- v2: mfplat: Support compressed WAVEFORMATEX in MFCreateWaveFormatExFromMFMediaType. mfplat: Support AAC format attributes in MFInitMediaTypeFromWaveFormatEx. mfplat/tests: Test MFWaveFormatExConvertFlag_ForceExtensible with HEAACWAVEFORMAT. mfplat/tests: Add MFInitMediaTypeFromWaveFormatEx tests with HEAACWAVEFORMAT. mfplat/tests: Test MFInitMediaTypeFromWaveFormatEx wrt MF_MT_FIXED_SIZE_SAMPLES. include: Add HEAACWAVEINFO and HEAACWAVEFORMAT definitions.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/tests/mfplat.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 7fab1598181..4560251cb8c 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -6947,6 +6947,11 @@ static void validate_media_type(IMFMediaType *mediatype, const WAVEFORMATEX *for } else ok(FAILED(hr), "Unexpected ALL_SAMPLES_INDEPENDENT.\n"); + + hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_FIXED_SIZE_SAMPLES, &value); + ok(FAILED(hr), "Unexpected FIXED_SIZE_SAMPLES.\n"); + hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_COMPRESSED, &value); + ok(FAILED(hr), "Unexpected COMPRESSED.\n"); }
static void test_MFInitMediaTypeFromWaveFormatEx(void)
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/tests/mfplat.c | 45 +++++++++++++++++++++++++++++++++++++- 1 file changed, 44 insertions(+), 1 deletion(-)
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 4560251cb8c..1f5479b84d6 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -6985,11 +6985,13 @@ static void test_MFInitMediaTypeFromWaveFormatEx(void) { WAVE_FORMAT_WMASPDIF }, };
- UINT8 buff[MPEGLAYER3_WFX_EXTRA_BYTES]; + UINT8 buff[1024]; WAVEFORMATEXTENSIBLE waveformatext; MPEGLAYER3WAVEFORMAT mp3format; + HEAACWAVEFORMAT aacformat; IMFMediaType *mediatype; unsigned int i, size; + UINT32 value; HRESULT hr;
hr = MFCreateMediaType(&mediatype); @@ -7042,6 +7044,47 @@ static void test_MFInitMediaTypeFromWaveFormatEx(void) ok(size == mp3format.wfx.cbSize, "Unexpected size %u.\n", size); ok(!memcmp(buff, (WAVEFORMATEX *)&mp3format + 1, size), "Unexpected user data.\n");
+ /* HEAACWAVEFORMAT */ + aacformat.wfInfo.wfx.wFormatTag = WAVE_FORMAT_MPEG_HEAAC; + aacformat.wfInfo.wfx.nChannels = 2; + aacformat.wfInfo.wfx.nSamplesPerSec = 44100; + aacformat.wfInfo.wfx.nAvgBytesPerSec = 16000; + aacformat.wfInfo.wfx.nBlockAlign = 1; + aacformat.wfInfo.wfx.wBitsPerSample = 0; + aacformat.wfInfo.wPayloadType = 2; + aacformat.wfInfo.wAudioProfileLevelIndication = 1; + aacformat.pbAudioSpecificConfig[0] = 0xcd; + + /* test with invalid format size */ + aacformat.wfInfo.wfx.cbSize = sizeof(aacformat) - 2 - sizeof(WAVEFORMATEX); + hr = MFInitMediaTypeFromWaveFormatEx(mediatype, (WAVEFORMATEX *)&aacformat, sizeof(aacformat) - 2); + todo_wine + ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr); + + aacformat.wfInfo.wfx.cbSize = sizeof(aacformat) - sizeof(WAVEFORMATEX); + hr = MFInitMediaTypeFromWaveFormatEx(mediatype, (WAVEFORMATEX *)&aacformat, sizeof(aacformat)); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + validate_media_type(mediatype, &aacformat.wfInfo.wfx); + + value = 0xdeadbeef; + hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, &value); + todo_wine + ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr); + todo_wine + ok(value == aacformat.wfInfo.wAudioProfileLevelIndication, "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 == S_OK, "Failed to get attribute, hr %#lx.\n", hr); + todo_wine + ok(value == aacformat.wfInfo.wPayloadType, "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"); + IMFMediaType_Release(mediatype); }
From: Rémi Bernon rbernon@codeweavers.com
--- include/mmreg.h | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
diff --git a/include/mmreg.h b/include/mmreg.h index 1b19e1f068f..f8024da8576 100644 --- a/include/mmreg.h +++ b/include/mmreg.h @@ -645,6 +645,22 @@ typedef struct mpeg1waveformat_tag { typedef MPEG1WAVEFORMAT *PMPEG1WAVEFORMAT, *NPMPEG1WAVEFORMAT, *LPMPEG1WAVEFORMAT;
+typedef struct +{ + WAVEFORMATEX wfx; + WORD wPayloadType; + WORD wAudioProfileLevelIndication; + WORD wStructType; + WORD wReserved1; + DWORD dwReserved2; +} HEAACWAVEINFO, *PHEAACWAVEINFO; + +typedef struct +{ + HEAACWAVEINFO wfInfo; + BYTE pbAudioSpecificConfig[1]; +} HEAACWAVEFORMAT, *PHEAACWAVEFORMAT; + #define ACM_MPEG_LAYER1 0x0001 #define ACM_MPEG_LAYER2 0x0002 #define ACM_MPEG_LAYER3 0x0004
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/tests/mfplat.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+)
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 1f5479b84d6..05633aaca52 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -6988,6 +6988,7 @@ static void test_MFInitMediaTypeFromWaveFormatEx(void) UINT8 buff[1024]; WAVEFORMATEXTENSIBLE waveformatext; MPEGLAYER3WAVEFORMAT mp3format; + WAVEFORMATEXTENSIBLE *format; HEAACWAVEFORMAT aacformat; IMFMediaType *mediatype; unsigned int i, size; @@ -7085,6 +7086,40 @@ 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");
+ hr = MFCreateWaveFormatExFromMFMediaType(mediatype, (WAVEFORMATEX **)&format, &size, MFWaveFormatExConvertFlag_ForceExtensible); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (hr == S_OK) + { + ok(format->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "got wFormatTag %#x\n", format->Format.wFormatTag); + 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(!memcmp(format + 1, &aacformat.wfInfo.wfx + 1, aacformat.wfInfo.wfx.cbSize), "Unexpected user data.\n"); + CoTaskMemFree(format); + } + + /* test with invalid format size */ + aacformat.wfInfo.wfx.cbSize = 1; + hr = IMFMediaType_SetBlob(mediatype, &MF_MT_USER_DATA, buff, aacformat.wfInfo.wfx.cbSize); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFCreateWaveFormatExFromMFMediaType(mediatype, (WAVEFORMATEX **)&format, &size, MFWaveFormatExConvertFlag_ForceExtensible); + todo_wine + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (hr == S_OK) + { + ok(format->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "got wFormatTag %#x\n", format->Format.wFormatTag); + 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(!memcmp(format + 1, &aacformat.wfInfo.wfx + 1, aacformat.wfInfo.wfx.cbSize), "Unexpected user data.\n"); + CoTaskMemFree(format); + } + IMFMediaType_Release(mediatype); }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/mediatype.c | 9 +++++++++ dlls/mfplat/tests/mfplat.c | 5 ----- 2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index 2ba967c6719..01890e77ce4 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -3124,6 +3124,15 @@ HRESULT WINAPI MFInitMediaTypeFromWaveFormatEx(IMFMediaType *mediatype, const WA mediatype_set_uint32(mediatype, &MF_MT_ALL_SAMPLES_INDEPENDENT, 1, &hr); }
+ if (IsEqualGUID(&subtype, &MFAudioFormat_AAC)) + { + HEAACWAVEINFO *info = CONTAINING_RECORD(format, HEAACWAVEINFO, wfx); + if (format->cbSize < sizeof(HEAACWAVEINFO) - sizeof(WAVEFORMATEX)) + return E_INVALIDARG; + mediatype_set_uint32(mediatype, &MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, info->wAudioProfileLevelIndication, &hr); + 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);
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 05633aaca52..19281c71151 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -7059,7 +7059,6 @@ static void test_MFInitMediaTypeFromWaveFormatEx(void) /* test with invalid format size */ aacformat.wfInfo.wfx.cbSize = sizeof(aacformat) - 2 - sizeof(WAVEFORMATEX); hr = MFInitMediaTypeFromWaveFormatEx(mediatype, (WAVEFORMATEX *)&aacformat, sizeof(aacformat) - 2); - todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#lx.\n", hr);
aacformat.wfInfo.wfx.cbSize = sizeof(aacformat) - sizeof(WAVEFORMATEX); @@ -7070,15 +7069,11 @@ static void test_MFInitMediaTypeFromWaveFormatEx(void)
value = 0xdeadbeef; hr = IMFMediaType_GetUINT32(mediatype, &MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, &value); - todo_wine ok(hr == S_OK, "Failed to get attribute, hr %#lx.\n", hr); - todo_wine ok(value == aacformat.wfInfo.wAudioProfileLevelIndication, "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 == S_OK, "Failed to get attribute, hr %#lx.\n", hr); - todo_wine ok(value == aacformat.wfInfo.wPayloadType, "Unexpected AAC_PAYLOAD_TYPE %u.\n", value);
hr = IMFMediaType_GetBlob(mediatype, &MF_MT_USER_DATA, buff, sizeof(buff), &size);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfplat/mediatype.c | 49 +++++++++++++++++--------------------- dlls/mfplat/tests/mfplat.c | 40 +++++++++++++------------------ 2 files changed, 38 insertions(+), 51 deletions(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index 01890e77ce4..0715ffec223 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -2963,10 +2963,9 @@ HRESULT WINAPI MFUnwrapMediaType(IMFMediaType *wrapper, IMFMediaType **ret) HRESULT WINAPI MFCreateWaveFormatExFromMFMediaType(IMFMediaType *mediatype, WAVEFORMATEX **ret_format, UINT32 *size, UINT32 flags) { - WAVEFORMATEXTENSIBLE *format_ext = NULL; + UINT32 value, extra_size = 0, user_size; WAVEFORMATEX *format; GUID major, subtype; - UINT32 value; HRESULT hr;
TRACE("%p, %p, %p, %#x.\n", mediatype, ret_format, size, flags); @@ -2980,36 +2979,23 @@ HRESULT WINAPI MFCreateWaveFormatExFromMFMediaType(IMFMediaType *mediatype, WAVE if (!IsEqualGUID(&major, &MFMediaType_Audio)) return E_INVALIDARG;
- if (!IsEqualGUID(&subtype, &MFAudioFormat_PCM) && !IsEqualGUID(&subtype, &MFAudioFormat_Float)) + if (FAILED(hr = IMFMediaType_GetBlobSize(mediatype, &MF_MT_USER_DATA, &user_size))) { - FIXME("Unsupported audio format %s.\n", debugstr_guid(&subtype)); - return E_NOTIMPL; + if (!IsEqualGUID(&subtype, &MFAudioFormat_PCM) && !IsEqualGUID(&subtype, &MFAudioFormat_Float)) + return hr; + user_size = 0; }
- /* FIXME: probably WAVE_FORMAT_MPEG/WAVE_FORMAT_MPEGLAYER3 should be handled separately. */ if (flags == MFWaveFormatExConvertFlag_ForceExtensible) - { - format_ext = CoTaskMemAlloc(sizeof(*format_ext)); - *size = sizeof(*format_ext); - format = (WAVEFORMATEX *)format_ext; - } - else - { - format = CoTaskMemAlloc(sizeof(*format)); - *size = sizeof(*format); - } + extra_size = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(*format);
- if (!format) + *size = sizeof(*format) + user_size + extra_size; + if (!(format = CoTaskMemAlloc(*size))) return E_OUTOFMEMORY;
memset(format, 0, *size); - - if (format_ext) - format->wFormatTag = WAVE_FORMAT_EXTENSIBLE; - else if (IsEqualGUID(&subtype, &MFAudioFormat_Float)) - format->wFormatTag = WAVE_FORMAT_IEEE_FLOAT; - else - format->wFormatTag = WAVE_FORMAT_PCM; + format->wFormatTag = subtype.Data1; + format->cbSize = user_size + extra_size;
if (SUCCEEDED(IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_NUM_CHANNELS, &value))) format->nChannels = value; @@ -3021,16 +3007,25 @@ HRESULT WINAPI MFCreateWaveFormatExFromMFMediaType(IMFMediaType *mediatype, WAVE format->nBlockAlign = value; if (SUCCEEDED(IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_BITS_PER_SAMPLE, &value))) format->wBitsPerSample = value; - if (format_ext) + + if (flags != MFWaveFormatExConvertFlag_ForceExtensible) + IMFMediaType_GetBlob(mediatype, &MF_MT_USER_DATA, (BYTE *)(format + 1), user_size, NULL); + else { - format->cbSize = sizeof(*format_ext) - sizeof(*format); + WAVEFORMATEXTENSIBLE *format_ext = CONTAINING_RECORD(format, WAVEFORMATEXTENSIBLE, Format); + + format_ext->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE; + format_ext->SubFormat = subtype;
if (SUCCEEDED(IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, &value))) format_ext->Samples.wSamplesPerBlock = value;
if (SUCCEEDED(IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_CHANNEL_MASK, &value))) format_ext->dwChannelMask = value; - memcpy(&format_ext->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM, sizeof(format_ext->SubFormat)); + else if (format_ext->Format.nChannels < ARRAY_SIZE(default_channel_mask)) + format_ext->dwChannelMask = default_channel_mask[format_ext->Format.nChannels]; + + IMFMediaType_GetBlob(mediatype, &MF_MT_USER_DATA, (BYTE *)(format_ext + 1), user_size, NULL); }
*ret_format = format; diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 19281c71151..f8cf51cad3b 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -7082,38 +7082,30 @@ static void test_MFInitMediaTypeFromWaveFormatEx(void) ok(!memcmp(buff, (WAVEFORMATEX *)&aacformat + 1, size), "Unexpected user data.\n");
hr = MFCreateWaveFormatExFromMFMediaType(mediatype, (WAVEFORMATEX **)&format, &size, MFWaveFormatExConvertFlag_ForceExtensible); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (hr == S_OK) - { - ok(format->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "got wFormatTag %#x\n", format->Format.wFormatTag); - 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(!memcmp(format + 1, &aacformat.wfInfo.wfx + 1, aacformat.wfInfo.wfx.cbSize), "Unexpected user data.\n"); - CoTaskMemFree(format); - } + ok(format->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "got wFormatTag %#x\n", format->Format.wFormatTag); + 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(!memcmp(format + 1, &aacformat.wfInfo.wfx + 1, aacformat.wfInfo.wfx.cbSize), "Unexpected user data.\n"); + CoTaskMemFree(format);
/* test with invalid format size */ aacformat.wfInfo.wfx.cbSize = 1; hr = IMFMediaType_SetBlob(mediatype, &MF_MT_USER_DATA, buff, aacformat.wfInfo.wfx.cbSize); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = MFCreateWaveFormatExFromMFMediaType(mediatype, (WAVEFORMATEX **)&format, &size, MFWaveFormatExConvertFlag_ForceExtensible); - todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - if (hr == S_OK) - { - ok(format->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "got wFormatTag %#x\n", format->Format.wFormatTag); - 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(!memcmp(format + 1, &aacformat.wfInfo.wfx + 1, aacformat.wfInfo.wfx.cbSize), "Unexpected user data.\n"); - CoTaskMemFree(format); - } + ok(format->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE, "got wFormatTag %#x\n", format->Format.wFormatTag); + 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(!memcmp(format + 1, &aacformat.wfInfo.wfx + 1, aacformat.wfInfo.wfx.cbSize), "Unexpected user data.\n"); + CoTaskMemFree(format);
IMFMediaType_Release(mediatype); }
v2: Added some tests with invalid sizes and use GetBlobSize instead of GetBlob.
Nikolay Sivov (@nsivov) commented about include/mmreg.h:
+typedef struct +{
- WAVEFORMATEX wfx;
- WORD wPayloadType;
- WORD wAudioProfileLevelIndication;
- WORD wStructType;
- WORD wReserved1;
- DWORD dwReserved2;
+} HEAACWAVEINFO, *PHEAACWAVEINFO;
+typedef struct +{
- HEAACWAVEINFO wfInfo;
- BYTE pbAudioSpecificConfig[1];
+} HEAACWAVEFORMAT, *PHEAACWAVEFORMAT;
These are using names for structures at least in 10.0.22621.0. The names are 'heaacwaveinfo_tag' and 'heaacwaveformat_tag'.
Nikolay Sivov (@nsivov) commented about dlls/mfplat/mediatype.c:
if (!IsEqualGUID(&major, &MFMediaType_Audio)) return E_INVALIDARG;
- if (!IsEqualGUID(&subtype, &MFAudioFormat_PCM) && !IsEqualGUID(&subtype, &MFAudioFormat_Float))
- if (FAILED(hr = IMFMediaType_GetBlobSize(mediatype, &MF_MT_USER_DATA, &user_size))) {
FIXME("Unsupported audio format %s.\n", debugstr_guid(&subtype));
return E_NOTIMPL;
if (!IsEqualGUID(&subtype, &MFAudioFormat_PCM) && !IsEqualGUID(&subtype, &MFAudioFormat_Float))
return hr;
}user_size = 0;
To check if attribute exists it's enough to use GetItem(key, NULL). Here it's fine of course, since you'll need user size anyway.
Nikolay Sivov (@nsivov) commented about dlls/mfplat/mediatype.c:
WAVEFORMATEXTENSIBLE *format_ext = CONTAINING_RECORD(format, WAVEFORMATEXTENSIBLE, Format);
format_ext->Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
format_ext->SubFormat = subtype; if (SUCCEEDED(IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_VALID_BITS_PER_SAMPLE, &value))) format_ext->Samples.wSamplesPerBlock = value; if (SUCCEEDED(IMFMediaType_GetUINT32(mediatype, &MF_MT_AUDIO_CHANNEL_MASK, &value))) format_ext->dwChannelMask = value;
memcpy(&format_ext->SubFormat, &KSDATAFORMAT_SUBTYPE_PCM, sizeof(format_ext->SubFormat));
else if (format_ext->Format.nChannels < ARRAY_SIZE(default_channel_mask))
format_ext->dwChannelMask = default_channel_mask[format_ext->Format.nChannels];
}IMFMediaType_GetBlob(mediatype, &MF_MT_USER_DATA, (BYTE *)(format_ext + 1), user_size, NULL);
I don't know if you'll see it as an improvement, but checking for flags equality here is another option, switching blocks around. Up to you.
On Fri Jan 19 15:57:40 2024 +0000, Nikolay Sivov wrote:
These are using names for structures at least in 10.0.22621.0. The names are 'heaacwaveinfo_tag' and 'heaacwaveformat_tag'.
Sure I'll add them, I wasn't sure if those did actually matter and thought only the typedefs did.
On Fri Jan 19 15:57:41 2024 +0000, Nikolay Sivov wrote:
To check if attribute exists it's enough to use GetItem(key, NULL). Here it's fine of course, since you'll need user size anyway.
Yes, I used GetBlob because I needed the size and didn't see that there was GetBlobSize for that. I was actually a bit surprised that I had to handle that specific error.