[PATCH 04/16] winegstreamer: Translate AAC caps to attributes.

Derek Lesho dlesho at codeweavers.com
Wed Mar 25 19:12:29 CDT 2020


Signed-off-by: Derek Lesho <dlesho at 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-types */
+                    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);
     }
-- 
2.25.1




More information about the wine-devel mailing list