[PATCH] winegstreamer: Fixup raw audio caps to be compatible with IMFMediaType.

Derek Lesho dlesho at codeweavers.com
Fri Nov 6 12:12:52 CST 2020


Signed-off-by: Derek Lesho <dlesho at codeweavers.com>
---
 dlls/winegstreamer/gst_private.h  |  1 +
 dlls/winegstreamer/media_source.c |  7 +++-
 dlls/winegstreamer/mfplat.c       | 57 +++++++++++++++++++++++++++++++
 3 files changed, 64 insertions(+), 1 deletion(-)

diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index 28e424439d8..75fc7dc90a8 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -78,6 +78,7 @@ void start_dispatch_thread(void) DECLSPEC_HIDDEN;
 extern HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) DECLSPEC_HIDDEN;
 
 HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
+GstCaps *make_mf_compatible_caps(GstCaps *caps) DECLSPEC_HIDDEN;
 IMFMediaType *mf_media_type_from_caps(const GstCaps *caps) DECLSPEC_HIDDEN;
 GstCaps *caps_from_mf_media_type(IMFMediaType *type) DECLSPEC_HIDDEN;
 IMFSample *mf_sample_from_gst_buffer(GstBuffer *in) DECLSPEC_HIDDEN;
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
index 828958e47e2..272dbfbfca6 100644
--- a/dlls/winegstreamer/media_source.c
+++ b/dlls/winegstreamer/media_source.c
@@ -869,15 +869,20 @@ fail:
 
 static HRESULT media_stream_init_desc(struct media_stream *stream)
 {
-    GstCaps *current_caps = gst_pad_get_current_caps(stream->their_src);
+    GstCaps *base_caps = gst_pad_get_current_caps(stream->their_src);
     IMFMediaTypeHandler *type_handler;
     IMFMediaType **stream_types = NULL;
     IMFMediaType *stream_type = NULL;
+    GstCaps *current_caps = make_mf_compatible_caps(base_caps);
     DWORD type_count = 0;
     const gchar *major_type;
     unsigned int i;
     HRESULT hr;
 
+    gst_caps_unref(base_caps);
+    if (!current_caps)
+        return E_FAIL;
+
     major_type = gst_structure_get_name(gst_caps_get_structure(current_caps, 0));
 
     if (!strcmp(major_type, "video/x-raw"))
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
index 3d224a5accc..7a877c2a416 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -602,6 +602,63 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
     return media_type;
 }
 
+GstCaps *make_mf_compatible_caps(GstCaps *caps)
+{
+    GstCaps *ret;
+    IMFMediaType *media_type;
+    GstStructure *structure;
+    const char *mime_type;
+
+    if (gst_caps_get_size(caps) != 1)
+        return NULL;
+
+    /* Optimization: Don't copy caps if no transformation is needed */
+    if ((media_type = mf_media_type_from_caps(caps)))
+    {
+        IMFMediaType_Release(media_type);
+        return gst_caps_ref(caps);
+    }
+
+    ret = gst_caps_copy(caps);
+    structure = gst_caps_get_structure(ret, 0);
+    mime_type = gst_structure_get_name(structure);
+
+    if (!strcmp(mime_type, "audio/x-raw"))
+    {
+        const char *format;
+        if ((format = gst_structure_get_string(structure, "format")))
+        {
+            char type;
+            unsigned int bits_per_sample;
+            char endian[2];
+            char new_format[6];
+
+            if (strlen(format) <= 5 && (sscanf(format, "%c%u%2c", &type, &bits_per_sample, endian) >= 2))
+            {
+                if (type == 'U' || type == 'S')
+                    type = bits_per_sample == 8 ? 'U' : 'S';
+
+                if (endian[0] == 'B')
+                    endian[0] = 'L';
+
+                sprintf(new_format, "%c%u%.2s", type, bits_per_sample, bits_per_sample > 8 ? endian : 0);
+                gst_caps_set_simple(caps, "format", G_TYPE_STRING, new_format, NULL);
+            }
+        }
+    }
+
+    if ((media_type = mf_media_type_from_caps(ret)))
+        IMFMediaType_Release(media_type);
+
+    if (!media_type)
+    {
+        gst_caps_unref(ret);
+        return NULL;
+    }
+
+    return ret;
+}
+
 GstCaps *caps_from_mf_media_type(IMFMediaType *type)
 {
     GUID major_type;
-- 
2.28.0




More information about the wine-devel mailing list