[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