[PATCH 4/6] winegstreamer: Introduce IMFMediaType -> GstCaps converter.

Derek Lesho dlesho at codeweavers.com
Tue Sep 29 17:08:54 CDT 2020


Signed-off-by: Derek Lesho <dlesho at codeweavers.com>
---
 dlls/winegstreamer/gst_private.h |   1 +
 dlls/winegstreamer/mfplat.c      | 149 +++++++++++++++++++++++++++++++
 2 files changed, 150 insertions(+)

diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index 60b38a48f5a..07556802a51 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -57,6 +57,7 @@ extern HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
 
 HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
 IMFMediaType *mf_media_type_from_caps(const GstCaps *caps) DECLSPEC_HIDDEN;
+GstCaps *caps_from_mf_media_type(IMFMediaType *type) DECLSPEC_HIDDEN;
 
 HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
 
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
index 2e8b0978648..9aa17ad00ab 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -601,3 +601,152 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
 
     return media_type;
 }
+
+GstCaps *caps_from_mf_media_type(IMFMediaType *type)
+{
+    GUID major_type;
+    GUID subtype;
+    GstCaps *output = NULL;
+
+    if (FAILED(IMFMediaType_GetMajorType(type, &major_type)))
+        return NULL;
+    if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype)))
+        return NULL;
+
+    if (IsEqualGUID(&major_type, &MFMediaType_Video))
+    {
+        UINT64 frame_rate = 0, frame_size = 0;
+        DWORD width, height, framerate_num, framerate_den;
+        UINT32 unused;
+
+        if (FAILED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size)))
+            return NULL;
+        width = frame_size >> 32;
+        height = frame_size;
+        if (FAILED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_RATE, &frame_rate)))
+        {
+            frame_rate = TRUE;
+            framerate_num = 0;
+            framerate_den = 1;
+        }
+        else
+        {
+            framerate_num = frame_rate >> 32;
+            framerate_den = frame_rate;
+        }
+
+        /* Check if type is uncompressed */
+        if (SUCCEEDED(MFCalculateImageSize(&subtype, 100, 100, &unused)))
+        {
+            GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
+            unsigned int i;
+
+            output = gst_caps_new_empty_simple("video/x-raw");
+
+            for (i = 0; i < ARRAY_SIZE(uncompressed_video_formats); i++)
+            {
+                if (IsEqualGUID(uncompressed_video_formats[i].subtype, &subtype))
+                {
+                    format = uncompressed_video_formats[i].format;
+                    break;
+                }
+            }
+
+            if (format == GST_VIDEO_FORMAT_UNKNOWN)
+            {
+                format = gst_video_format_from_fourcc(subtype.Data1);
+            }
+
+            if (format == GST_VIDEO_FORMAT_UNKNOWN)
+            {
+                FIXME("Unrecognized format %s\n", debugstr_guid(&subtype));
+                return NULL;
+            }
+            else
+            {
+                GstVideoInfo info;
+
+                gst_video_info_set_format(&info, format, width, height);
+                output = gst_video_info_to_caps(&info);
+            }
+
+        }
+        else {
+            FIXME("Unrecognized subtype %s\n", debugstr_guid(&subtype));
+            return NULL;
+        }
+
+
+        if (frame_size)
+        {
+            gst_caps_set_simple(output, "width", G_TYPE_INT, width, NULL);
+            gst_caps_set_simple(output, "height", G_TYPE_INT, height, NULL);
+        }
+        if (frame_rate)
+            gst_caps_set_simple(output, "framerate", GST_TYPE_FRACTION, framerate_num, framerate_den, NULL);
+        return output;
+    }
+    else if (IsEqualGUID(&major_type, &MFMediaType_Audio))
+    {
+        DWORD rate, channels, channel_mask, bitrate;
+
+        if (IsEqualGUID(&subtype, &MFAudioFormat_Float))
+        {
+            output = gst_caps_new_empty_simple("audio/x-raw");
+
+            gst_caps_set_simple(output, "format", G_TYPE_STRING, "F32LE", NULL);
+            gst_caps_set_simple(output, "layout", G_TYPE_STRING, "interleaved", NULL);
+        }
+        else if (IsEqualGUID(&subtype, &MFAudioFormat_PCM))
+        {
+            DWORD bits_per_sample;
+
+            if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &bits_per_sample)))
+            {
+                char format[6];
+                char type;
+
+                type = bits_per_sample > 8 ? 'S' : 'U';
+
+                output = gst_caps_new_empty_simple("audio/x-raw");
+
+                sprintf(format, "%c%u%s", type, bits_per_sample, bits_per_sample > 8 ? "LE" : "");
+
+                gst_caps_set_simple(output, "format", G_TYPE_STRING, format, NULL);
+            }
+            else
+            {
+                ERR("Bits per sample not set.\n");
+                return NULL;
+            }
+        }
+        else
+        {
+            FIXME("Unrecognized subtype %s\n", debugstr_guid(&subtype));
+            return NULL;
+        }
+
+        if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &rate)))
+        {
+            gst_caps_set_simple(output, "rate", G_TYPE_INT, rate, NULL);
+        }
+        if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &channels)))
+        {
+            gst_caps_set_simple(output, "channels", G_TYPE_INT, channels, NULL);
+        }
+        if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_CHANNEL_MASK, &channel_mask)))
+        {
+            gst_caps_set_simple(output, "channel-mask", GST_TYPE_BITMASK, (guint64) channel_mask, NULL);
+        }
+
+        if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_AVG_BITRATE, &bitrate)))
+        {
+            gst_caps_set_simple(output, "bitrate", G_TYPE_INT, bitrate, NULL);
+        }
+
+        return output;
+    }
+
+    FIXME("Unrecognized major type %s\n", debugstr_guid(&major_type));
+    return NULL;
+}
-- 
2.28.0




More information about the wine-devel mailing list