Signed-off-by: Derek Lesho dlesho@codeweavers.com --- dlls/winegstreamer/mfplat.c | 119 ++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+)
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c index a56ec1d6e6..c98c8b897a 100644 --- a/dlls/winegstreamer/mfplat.c +++ b/dlls/winegstreamer/mfplat.c @@ -440,6 +440,15 @@ HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) return CLASS_E_CLASSNOTAVAILABLE; }
+struct aac_user_data +{ + WORD payload_type; + WORD profile_level_indication; + WORD struct_type; + WORD reserved; + /*BYTE audio_specific_config;*/ +}; + /* IMPORTANT: caps will be modified to represent the exact type needed for the format */ IMFMediaType* media_type_from_caps(GstCaps *caps) { @@ -607,6 +616,116 @@ IMFMediaType* media_type_from_caps(GstCaps *caps)
gst_caps_set_simple(caps, "format", G_TYPE_STRING, "F32LE", NULL); } + else if (!(strcmp(mime_type, "audio/mpeg"))) + { + int mpeg_version = -1; + + IMFMediaType_SetUINT32(media_type, &MF_MT_COMPRESSED, TRUE); + + if (!(gst_structure_get_int(info, "mpegversion", &mpeg_version))) + ERR("Failed to get mpegversion\n"); + switch (mpeg_version) + { + case 1: + { + IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_MPEG); + break; + } + case 2: + case 4: + { + const char *format, *profile, *level; + DWORD profile_level_indication = 0; + const GValue *codec_data; + DWORD asc_size = 0; + struct aac_user_data *user_data = NULL; + + IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_AAC); + + codec_data = gst_structure_get_value(info, "codec_data"); + if (codec_data) + { + GstBuffer *codec_data_buffer = gst_value_get_buffer(codec_data); + if (codec_data_buffer) + { + if ((asc_size = gst_buffer_get_size(codec_data_buffer)) >= 2) + { + user_data = heap_alloc_zero(sizeof(*user_data)+asc_size); + gst_buffer_extract(codec_data_buffer, 0, (gpointer)(user_data + 1), asc_size); + } + else + ERR("Unexpected buffer size\n"); + } + else + ERR("codec_data not a buffer\n"); + } + else + ERR("codec_data not found\n"); + if (!user_data) + user_data = heap_alloc_zero(sizeof(*user_data)); + + { + int rate; + if (gst_structure_get_int(info, "rate", &rate)) + IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, rate); + } + { + int channels; + if (gst_structure_get_int(info, "channels", &channels)) + IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_NUM_CHANNELS, channels); + } + + if ((format = gst_structure_get_string(info, "stream-format"))) + { + DWORD payload_type = -1; + if (!(strcmp(format, "raw"))) + payload_type = 0; + else if (!(strcmp(format, "adts"))) + payload_type = 1; + else + ERR("Unrecognized stream-format\n"); + if (payload_type != -1) + { + IMFMediaType_SetUINT32(media_type, &MF_MT_AAC_PAYLOAD_TYPE, payload_type); + user_data->payload_type = payload_type; + } + } + else + { + ERR("Stream format not present\n"); + } + + profile = gst_structure_get_string(info, "profile"); + level = gst_structure_get_string(info, "level"); + /* Data from https://docs.microsoft.com/en-us/windows/win32/medfound/aac-encoder#output-t... */ + if (profile && level) + { + if (!(strcmp(profile, "lc")) && !(strcmp(level, "2"))) + profile_level_indication = 0x29; + else if (!(strcmp(profile, "lc")) && !(strcmp(level, "4"))) + profile_level_indication = 0x2A; + else if (!(strcmp(profile, "lc")) && !(strcmp(level, "5"))) + profile_level_indication = 0x2B; + else + ERR("Unhandled profile/level combo\n"); + } + else + ERR("Profile or level not present\n"); + + if (profile_level_indication) + { + IMFMediaType_SetUINT32(media_type, &MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, profile_level_indication); + user_data->profile_level_indication = profile_level_indication; + } + + IMFMediaType_SetBlob(media_type, &MF_MT_USER_DATA, (BYTE *)user_data, sizeof(user_data) + asc_size); + heap_free(user_data); + break; + } + default: + ERR("Unhandled mpegversion %d\n", mpeg_version); + } + } else ERR("Unrecognized audio format %s\n", mime_type); }