[PATCH 11/16] winegstreamer: Introduce IMFMediaType -> GstCaps converter.

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


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

diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index 49691d1fbe..e594ed1419 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -56,6 +56,7 @@ void start_dispatch_thread(void) DECLSPEC_HIDDEN;
 extern HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) DECLSPEC_HIDDEN;
 
 IMFMediaType* media_type_from_caps(GstCaps *caps);
+GstCaps *caps_from_media_type(IMFMediaType *type);
 IMFSample* mf_sample_from_gst_buffer(GstBuffer *in);
 
 enum source_type
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
index 54b611b130..b7aef27645 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -751,6 +751,89 @@ IMFMediaType* media_type_from_caps(GstCaps *caps)
     return NULL;
 }
 
+static const char *fourcc_str(DWORD fourcc)
+{
+    if (!fourcc) return NULL;
+    return wine_dbg_sprintf ("%c%c%c%c",
+        (char)(fourcc), (char)(fourcc >> 8),
+        (char)(fourcc >> 16), (char)(fourcc >> 24));
+}
+
+GstCaps *caps_from_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 *framerate_num = ((DWORD*)&frame_rate) + 1;
+        DWORD *framerate_den = ((DWORD*)&frame_rate);
+        DWORD *width = ((DWORD*)&frame_size) + 1;
+        DWORD *height = ((DWORD*)&frame_size);
+        UINT32 unused;
+
+        /* Check if type is uncompressed */
+        if (SUCCEEDED(MFCalculateImageSize(&subtype, 100, 100, &unused)))
+        {
+            output = gst_caps_new_empty_simple("video/x-raw");
+            gst_caps_set_simple(output, "format", G_TYPE_STRING, fourcc_str(subtype.Data1), NULL);
+        }
+        else {
+            ERR("Unrecognized subtype %s\n", debugstr_guid(&subtype));
+            return NULL;
+        }
+
+        IMFMediaType_GetUINT64(type, &MF_MT_FRAME_RATE, &frame_rate);
+        IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size);
+
+        if (frame_rate)
+            gst_caps_set_simple(output, "framerate", GST_TYPE_FRACTION, *framerate_num, *framerate_den, 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);
+        }
+        return output;
+    }
+    else if (IsEqualGUID(&major_type, &MFMediaType_Audio))
+    {
+        DWORD rate, channels;
+
+        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);
+        }
+        else
+        {
+            ERR("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);
+        }
+
+        return output;
+    }
+
+    ERR("Unrecognized major type %s\n", debugstr_guid(&major_type));
+    return NULL;
+}
+
 /* IMFSample = GstBuffer
    IMFBuffer = GstMemory */
 
-- 
2.25.1




More information about the wine-devel mailing list