mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2025-01-28 22:04:43 -08:00
Updated mfplat-streaming-support patchset
This commit is contained in:
parent
6d726da3ba
commit
601cfd7fdb
@ -0,0 +1,32 @@
|
||||
From 5b02ea1ed7f44fba8070b9a2ef69b78eb02bf3d7 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Wed, 14 Oct 2020 11:07:05 -0500
|
||||
Subject: [PATCH] mf: Unconditionally deliver NULL (EOS) samples.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/mf/session.c | 5 +++--
|
||||
1 file changed, 3 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/mf/session.c b/dlls/mf/session.c
|
||||
index a1b54b7080e..7c82aa42a4b 100644
|
||||
--- a/dlls/mf/session.c
|
||||
+++ b/dlls/mf/session.c
|
||||
@@ -2599,11 +2599,12 @@ static void session_deliver_sample_to_node(struct media_session *session, IMFTop
|
||||
LIST_FOR_EACH_ENTRY_SAFE(sample_entry, sample_entry2, &topo_node->u.transform.outputs[i].samples,
|
||||
struct sample, entry)
|
||||
{
|
||||
- if (!topo_node->u.transform.outputs[i].requests)
|
||||
+ if (!topo_node->u.transform.outputs[i].requests && sample_entry->sample)
|
||||
break;
|
||||
|
||||
session_deliver_sample_to_node(session, downstream_node, downstream_input, sample_entry->sample);
|
||||
- topo_node->u.transform.outputs[i].requests--;
|
||||
+ if (sample_entry->sample)
|
||||
+ topo_node->u.transform.outputs[i].requests--;
|
||||
|
||||
transform_release_sample(sample_entry);
|
||||
}
|
||||
--
|
||||
2.28.0
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 99b43be87b11803938b12b08298406391b77d510 Mon Sep 17 00:00:00 2001
|
||||
From fed4032224546cabe827c6621d31d5a72d11c05e Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 25 Aug 2020 17:35:49 -0500
|
||||
Subject: [PATCH] winegstreamer: Insert videoconvert into decoded-video
|
||||
@ -6,20 +6,31 @@ Subject: [PATCH] winegstreamer: Insert videoconvert into decoded-video
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/media_source.c | 104 ++++++++++++++++++++++++------
|
||||
1 file changed, 85 insertions(+), 19 deletions(-)
|
||||
dlls/winegstreamer/media_source.c | 125 ++++++++++++++++++++++++++----
|
||||
1 file changed, 111 insertions(+), 14 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
|
||||
index 92b4100f7bc..a9aff0eb296 100644
|
||||
index 5f3c43a0204..258b8c2dfb1 100644
|
||||
--- a/dlls/winegstreamer/media_source.c
|
||||
+++ b/dlls/winegstreamer/media_source.c
|
||||
@@ -430,8 +430,22 @@ static HRESULT media_stream_align_with_mf(struct media_stream *stream)
|
||||
g_free(source_caps_str);
|
||||
}
|
||||
@@ -384,6 +384,43 @@ static const IMFMediaStreamVtbl media_stream_vtbl =
|
||||
media_stream_RequestSample
|
||||
};
|
||||
|
||||
- if (!strcmp(gst_structure_get_name(gst_caps_get_structure(source_caps, 0)), "video/x-raw") ||
|
||||
- !strcmp(gst_structure_get_name(gst_caps_get_structure(source_caps, 0)), "audio/x-raw"))
|
||||
+ if (!strcmp(gst_structure_get_name(gst_caps_get_structure(source_caps, 0)), "video/x-raw"))
|
||||
+/* Setup a chain of elements which should hopefully allow transformations to any IMFMediaType
|
||||
+ the user throws at us through gstreamer's caps negotiation. */
|
||||
+static HRESULT media_stream_connect_to_sink(struct media_stream *stream)
|
||||
+{
|
||||
+ GstCaps *source_caps = gst_pad_query_caps(stream->their_src, NULL);
|
||||
+ const gchar *stream_type;
|
||||
+
|
||||
+ if (!source_caps)
|
||||
+ return E_FAIL;
|
||||
+
|
||||
+ stream_type = gst_structure_get_name(gst_caps_get_structure(source_caps, 0));
|
||||
+ gst_caps_unref(source_caps);
|
||||
+
|
||||
+ if (!strcmp(stream_type, "video/x-raw"))
|
||||
+ {
|
||||
+ GstElement *videoconvert = gst_element_factory_make("videoconvert", NULL);
|
||||
+
|
||||
@ -27,115 +38,128 @@ index 92b4100f7bc..a9aff0eb296 100644
|
||||
+
|
||||
+ stream->my_sink = gst_element_get_static_pad(videoconvert, "sink");
|
||||
+
|
||||
+ assert(gst_pad_link(stream->their_src, stream->my_sink) == GST_PAD_LINK_OK);
|
||||
+ assert(gst_element_link(videoconvert, stream->appsink));
|
||||
+ if (!gst_element_link(videoconvert, stream->appsink))
|
||||
+ return E_FAIL;
|
||||
+
|
||||
+ gst_element_sync_state_with_parent(videoconvert);
|
||||
+
|
||||
+ g_object_set(stream->appsink, "caps", source_caps, NULL);
|
||||
+ }
|
||||
+ else if(!strcmp(gst_structure_get_name(gst_caps_get_structure(source_caps, 0)), "audio/x-raw"))
|
||||
{
|
||||
stream->my_sink = gst_element_get_static_pad(stream->appsink, "sink");
|
||||
g_object_set(stream->appsink, "caps", source_caps, NULL);
|
||||
@@ -569,37 +583,89 @@ static HRESULT media_stream_init_desc(struct media_stream *stream)
|
||||
+ else
|
||||
+ {
|
||||
+ stream->my_sink = gst_element_get_static_pad(stream->appsink, "sink");
|
||||
+ }
|
||||
+
|
||||
+ if (gst_pad_link(stream->their_src, stream->my_sink) != GST_PAD_LINK_OK)
|
||||
+ return E_FAIL;
|
||||
+
|
||||
+ return S_OK;
|
||||
+}
|
||||
+
|
||||
static HRESULT new_media_stream(struct media_source *source, GstPad *pad, DWORD stream_id, struct media_stream **out_stream)
|
||||
{
|
||||
struct media_stream *object = heap_alloc_zero(sizeof(*object));
|
||||
@@ -414,8 +451,8 @@ static HRESULT new_media_stream(struct media_source *source, GstPad *pad, DWORD
|
||||
g_object_set(object->appsink, "sync", FALSE, NULL);
|
||||
g_object_set(object->appsink, "max-buffers", 5, NULL);
|
||||
|
||||
- object->my_sink = gst_element_get_static_pad(object->appsink, "sink");
|
||||
- gst_pad_link(object->their_src, object->my_sink);
|
||||
+ if (FAILED(hr = media_stream_connect_to_sink(object)))
|
||||
+ goto fail;
|
||||
|
||||
gst_element_sync_state_with_parent(object->appsink);
|
||||
|
||||
@@ -435,28 +472,88 @@ static HRESULT media_stream_init_desc(struct media_stream *stream)
|
||||
{
|
||||
GstCaps *current_caps = gst_pad_get_current_caps(stream->their_src);
|
||||
IMFMediaTypeHandler *type_handler;
|
||||
+ IMFMediaType **stream_types = NULL;
|
||||
IMFMediaType *stream_type = NULL;
|
||||
+ DWORD type_count = 0;
|
||||
+ const gchar *major_type;
|
||||
+ unsigned int i;
|
||||
HRESULT hr;
|
||||
|
||||
- if (strcmp(gst_structure_get_name(gst_caps_get_structure(current_caps, 0)), "video/x-raw") &&
|
||||
- strcmp(gst_structure_get_name(gst_caps_get_structure(current_caps, 0)), "audio/x-raw"))
|
||||
+ if (!strcmp(gst_structure_get_name(gst_caps_get_structure(current_caps, 0)), "video/x-raw"))
|
||||
{
|
||||
- GstCaps *compatible_caps = make_mf_compatible_caps(current_caps);
|
||||
- stream_type = mf_media_type_from_caps(compatible_caps);
|
||||
- gst_caps_unref(compatible_caps);
|
||||
+ GstElementFactory *videoconvert_factory = gst_element_factory_find("videoconvert");
|
||||
+ /* output every format supported by videoconvert */
|
||||
+ const GList *template_list = gst_element_factory_get_static_pad_templates(videoconvert_factory);
|
||||
+ for (;template_list; template_list = template_list->next)
|
||||
+ {
|
||||
+ GstStaticPadTemplate *template = (GstStaticPadTemplate *)template_list->data;
|
||||
+ GstCaps *src_caps;
|
||||
+ GValueArray *formats;
|
||||
+ if (template->direction != GST_PAD_SRC)
|
||||
+ continue;
|
||||
+ src_caps = gst_static_pad_template_get_caps(template);
|
||||
+ gst_structure_get_list(gst_caps_get_structure(src_caps, 0), "format", &formats);
|
||||
+ stream_types = heap_alloc( sizeof(IMFMediaType*) * formats->n_values );
|
||||
+ for (i = 0; i < formats->n_values; i++)
|
||||
+ {
|
||||
+ GValue *format = g_value_array_get_nth(formats, i);
|
||||
+ GstCaps *modified_caps = gst_caps_copy(current_caps);
|
||||
+ gst_caps_set_value(modified_caps, "format", format);
|
||||
+ stream_types[type_count] = mf_media_type_from_caps(modified_caps);
|
||||
+ gst_caps_unref(modified_caps);
|
||||
+ if (stream_types[type_count])
|
||||
+ type_count++;
|
||||
+ }
|
||||
+ g_value_array_free(formats);
|
||||
+ gst_caps_unref(src_caps);
|
||||
+ break;
|
||||
+ }
|
||||
}
|
||||
- else
|
||||
+ else if (!strcmp(gst_structure_get_name(gst_caps_get_structure(current_caps, 0)), "audio/x-raw"))
|
||||
- stream_type = mf_media_type_from_caps(current_caps);
|
||||
- gst_caps_unref(current_caps);
|
||||
- if (!stream_type)
|
||||
- return E_FAIL;
|
||||
+ major_type = gst_structure_get_name(gst_caps_get_structure(current_caps, 0));
|
||||
+
|
||||
+ if (!strcmp(major_type, "video/x-raw"))
|
||||
+ {
|
||||
stream_type = mf_media_type_from_caps(current_caps);
|
||||
+ /* These are the most common native output types of decoders:
|
||||
+ https://docs.microsoft.com/en-us/windows/win32/medfound/mft-decoder-expose-output-types-in-native-order */
|
||||
+ static const GUID *const video_types[] =
|
||||
+ {
|
||||
+ &MFVideoFormat_NV12,
|
||||
+ &MFVideoFormat_YV12,
|
||||
+ &MFVideoFormat_YUY2,
|
||||
+ &MFVideoFormat_IYUV,
|
||||
+ &MFVideoFormat_I420,
|
||||
+ };
|
||||
|
||||
- hr = MFCreateStreamDescriptor(stream->stream_id, 1, &stream_type, &stream->descriptor);
|
||||
+ IMFMediaType *base_type = mf_media_type_from_caps(current_caps);
|
||||
+ GUID base_subtype;
|
||||
|
||||
- IMFMediaType_Release(stream_type);
|
||||
+ IMFMediaType_GetGUID(base_type, &MF_MT_SUBTYPE, &base_subtype);
|
||||
|
||||
- if (FAILED(hr))
|
||||
- return hr;
|
||||
+ stream_types = heap_alloc( sizeof(IMFMediaType *) * ARRAY_SIZE(video_types) + 1);
|
||||
|
||||
- if (FAILED(hr = IMFStreamDescriptor_GetMediaTypeHandler(stream->descriptor, &type_handler)))
|
||||
- return hr;
|
||||
+ stream_types[0] = base_type;
|
||||
+ type_count = 1;
|
||||
|
||||
- hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, stream_type);
|
||||
+ for (i = 0; i < ARRAY_SIZE(video_types); i++)
|
||||
+ {
|
||||
+ IMFMediaType *new_type;
|
||||
|
||||
- IMFMediaTypeHandler_Release(type_handler);
|
||||
+ if (IsEqualGUID(&base_subtype, video_types[i]))
|
||||
+ continue;
|
||||
|
||||
+ if (FAILED(hr = MFCreateMediaType(&new_type)))
|
||||
+ goto done;
|
||||
+ stream_types[type_count++] = new_type;
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaType_CopyAllItems(base_type, (IMFAttributes *) new_type)))
|
||||
+ goto done;
|
||||
+ if (FAILED(hr = IMFMediaType_SetGUID(new_type, &MF_MT_SUBTYPE, video_types[i])))
|
||||
+ goto done;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ stream_type = mf_media_type_from_caps(current_caps);
|
||||
+ if (stream_type)
|
||||
+ {
|
||||
+ stream_types = &stream_type;
|
||||
+ type_count = 1;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ GstCaps *compatible_caps = make_mf_compatible_caps(current_caps);
|
||||
+ if (compatible_caps)
|
||||
+ {
|
||||
+ stream_type = mf_media_type_from_caps(compatible_caps);
|
||||
+ gst_caps_unref(compatible_caps);
|
||||
+ if (stream_type)
|
||||
+ {
|
||||
+ stream_types = &stream_type;
|
||||
+ type_count = 1;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
|
||||
gst_caps_unref(current_caps);
|
||||
- if (!stream_type)
|
||||
+
|
||||
+ if (!type_count)
|
||||
+ {
|
||||
+ ERR("Failed to establish an IMFMediaType from any of the possible stream caps!\n");
|
||||
return E_FAIL;
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
|
||||
- hr = MFCreateStreamDescriptor(stream->stream_id, 1, &stream_type, &stream->descriptor);
|
||||
-
|
||||
- IMFMediaType_Release(stream_type);
|
||||
-
|
||||
- if (FAILED(hr))
|
||||
- return hr;
|
||||
+
|
||||
+ if (FAILED(hr = MFCreateStreamDescriptor(stream->stream_id, type_count, stream_types, &stream->descriptor)))
|
||||
+ goto done;
|
||||
|
||||
if (FAILED(hr = IMFStreamDescriptor_GetMediaTypeHandler(stream->descriptor, &type_handler)))
|
||||
- return hr;
|
||||
-
|
||||
- hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, stream_type);
|
||||
+
|
||||
+ if (FAILED(hr = IMFStreamDescriptor_GetMediaTypeHandler(stream->descriptor, &type_handler)))
|
||||
+ goto done;
|
||||
|
||||
- IMFMediaTypeHandler_Release(type_handler);
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, stream_types[0])))
|
||||
+ goto done;
|
||||
|
||||
+
|
||||
+done:
|
||||
+ gst_caps_unref(current_caps);
|
||||
+ if (type_handler)
|
||||
+ IMFMediaTypeHandler_Release(type_handler);
|
||||
+ for (i = 0; i < type_count; i++)
|
||||
|
@ -1,4 +1,4 @@
|
||||
From b5f1fc2793dce6165b509cc326163d71601d963c Mon Sep 17 00:00:00 2001
|
||||
From 87976eb22d5dc1f453edbdf713a768d67d83b1c4 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 25 Aug 2020 17:37:28 -0500
|
||||
Subject: [PATCH] winegstreamer: Insert audioconvert into decoded audio
|
||||
@ -6,34 +6,33 @@ Subject: [PATCH] winegstreamer: Insert audioconvert into decoded audio
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/media_source.c | 13 +++++++++++--
|
||||
1 file changed, 11 insertions(+), 2 deletions(-)
|
||||
dlls/winegstreamer/media_source.c | 13 +++++++++++++
|
||||
1 file changed, 13 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
|
||||
index a9aff0eb296..6190ac57e0e 100644
|
||||
index 258b8c2dfb1..d6c7837e544 100644
|
||||
--- a/dlls/winegstreamer/media_source.c
|
||||
+++ b/dlls/winegstreamer/media_source.c
|
||||
@@ -447,9 +447,18 @@ static HRESULT media_stream_align_with_mf(struct media_stream *stream)
|
||||
@@ -410,6 +410,19 @@ static HRESULT media_stream_connect_to_sink(struct media_stream *stream)
|
||||
|
||||
gst_element_sync_state_with_parent(videoconvert);
|
||||
}
|
||||
else if(!strcmp(gst_structure_get_name(gst_caps_get_structure(source_caps, 0)), "audio/x-raw"))
|
||||
{
|
||||
- stream->my_sink = gst_element_get_static_pad(stream->appsink, "sink");
|
||||
- g_object_set(stream->appsink, "caps", source_caps, NULL);
|
||||
+ else if (!strcmp(stream_type, "audio/x-raw"))
|
||||
+ {
|
||||
+ GstElement *audioconvert = gst_element_factory_make("audioconvert", NULL);
|
||||
+
|
||||
+ gst_bin_add(GST_BIN(stream->parent_source->container), audioconvert);
|
||||
+
|
||||
+ stream->my_sink = gst_element_get_static_pad(audioconvert, "sink");
|
||||
+
|
||||
assert(gst_pad_link(stream->their_src, stream->my_sink) == GST_PAD_LINK_OK);
|
||||
+ assert(gst_element_link(audioconvert, stream->appsink));
|
||||
+ if (!gst_element_link(audioconvert, stream->appsink))
|
||||
+ return E_FAIL;
|
||||
+
|
||||
+ gst_element_sync_state_with_parent(audioconvert);
|
||||
+
|
||||
+ g_object_set(stream->appsink, "caps", source_caps, NULL);
|
||||
}
|
||||
+ }
|
||||
else
|
||||
{
|
||||
stream->my_sink = gst_element_get_static_pad(stream->appsink, "sink");
|
||||
--
|
||||
2.28.0
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 2fe4bd639fe92f050ab4c0be2a5e586d4ae5852a Mon Sep 17 00:00:00 2001
|
||||
From 577e9cb7c2370660c9e0acd1b409dcca398290e0 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 31 Mar 2020 11:21:21 -0500
|
||||
Subject: [PATCH] winegstreamer: Implement
|
||||
@ -6,12 +6,25 @@ Subject: [PATCH] winegstreamer: Implement
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/mfplat/tests/mfplat.c | 9 ++++----
|
||||
dlls/winegstreamer/media_source.c | 36 +++++++++++++++++++++++++++++--
|
||||
2 files changed, 38 insertions(+), 7 deletions(-)
|
||||
dlls/mf/tests/mf.c | 1 -
|
||||
dlls/mfplat/tests/mfplat.c | 10 +++++-----
|
||||
dlls/winegstreamer/media_source.c | 28 ++++++++++++++++++++++++++--
|
||||
3 files changed, 31 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
|
||||
index 351a6e1edab..e6f3593a74b 100644
|
||||
--- a/dlls/mf/tests/mf.c
|
||||
+++ b/dlls/mf/tests/mf.c
|
||||
@@ -1451,7 +1451,6 @@ todo_wine
|
||||
return;
|
||||
|
||||
hr = IMFMediaSource_CreatePresentationDescriptor(source, &pd);
|
||||
-todo_wine
|
||||
ok(hr == S_OK, "Failed to create descriptor, hr %#x.\n", hr);
|
||||
if (FAILED(hr))
|
||||
return;
|
||||
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
|
||||
index 309f7b669a4..72d06e31880 100644
|
||||
index 55c07adb1fe..7491b53896f 100644
|
||||
--- a/dlls/mfplat/tests/mfplat.c
|
||||
+++ b/dlls/mfplat/tests/mfplat.c
|
||||
@@ -576,10 +576,7 @@ static void test_source_resolver(void)
|
||||
@ -25,7 +38,15 @@ index 309f7b669a4..72d06e31880 100644
|
||||
ok(descriptor != NULL, "got %p\n", descriptor);
|
||||
|
||||
hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(descriptor, 0, &selected, &sd);
|
||||
@@ -607,7 +604,10 @@ todo_wine
|
||||
@@ -599,6 +596,7 @@ todo_wine
|
||||
ok(hr == S_OK, "Failed to get current media type, hr %#x.\n", hr);
|
||||
hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &guid);
|
||||
ok(hr == S_OK, "Failed to get media sub type, hr %#x.\n", hr);
|
||||
+todo_wine
|
||||
ok(IsEqualGUID(&guid, &MFVideoFormat_M4S2), "Unexpected sub type %s.\n", debugstr_guid(&guid));
|
||||
IMFMediaType_Release(media_type);
|
||||
|
||||
@@ -607,7 +605,10 @@ todo_wine
|
||||
|
||||
var.vt = VT_EMPTY;
|
||||
hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
|
||||
@ -36,7 +57,7 @@ index 309f7b669a4..72d06e31880 100644
|
||||
|
||||
get_event((IMFMediaEventGenerator *)mediasource, MENewStream, &var);
|
||||
ok(var.vt == VT_UNKNOWN, "Unexpected value type %u from MENewStream event.\n", var.vt);
|
||||
@@ -670,11 +670,10 @@ todo_wine
|
||||
@@ -670,11 +671,10 @@ todo_wine
|
||||
|
||||
get_event((IMFMediaEventGenerator *)mediasource, MEEndOfPresentation, NULL);
|
||||
|
||||
@ -50,7 +71,7 @@ index 309f7b669a4..72d06e31880 100644
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
|
||||
index 6190ac57e0e..5f203a946bc 100644
|
||||
index d6c7837e544..9b2c2174318 100644
|
||||
--- a/dlls/winegstreamer/media_source.c
|
||||
+++ b/dlls/winegstreamer/media_source.c
|
||||
@@ -67,6 +67,7 @@ struct media_source
|
||||
@ -61,7 +82,7 @@ index 6190ac57e0e..5f203a946bc 100644
|
||||
GstBus *bus;
|
||||
GstElement *container;
|
||||
GstElement *decodebin;
|
||||
@@ -781,12 +782,19 @@ static HRESULT WINAPI media_source_CreatePresentationDescriptor(IMFMediaSource *
|
||||
@@ -673,12 +674,12 @@ static HRESULT WINAPI media_source_CreatePresentationDescriptor(IMFMediaSource *
|
||||
{
|
||||
struct media_source *source = impl_from_IMFMediaSource(iface);
|
||||
|
||||
@ -72,18 +93,11 @@ index 6190ac57e0e..5f203a946bc 100644
|
||||
return MF_E_SHUTDOWN;
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ if (!(source->pres_desc))
|
||||
+ {
|
||||
+ return MF_E_NOT_INITIALIZED;
|
||||
+ }
|
||||
+
|
||||
+ IMFPresentationDescriptor_Clone(source->pres_desc, descriptor);
|
||||
+
|
||||
+ return S_OK;
|
||||
+ return IMFPresentationDescriptor_Clone(source->pres_desc, descriptor);
|
||||
}
|
||||
|
||||
static HRESULT WINAPI media_source_Start(IMFMediaSource *iface, IMFPresentationDescriptor *descriptor,
|
||||
@@ -849,6 +857,8 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface)
|
||||
@@ -741,6 +742,8 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface)
|
||||
if (source->their_sink)
|
||||
gst_object_unref(GST_OBJECT(source->their_sink));
|
||||
|
||||
@ -92,7 +106,7 @@ index 6190ac57e0e..5f203a946bc 100644
|
||||
if (source->event_queue)
|
||||
IMFMediaEventQueue_Shutdown(source->event_queue);
|
||||
if (source->byte_stream)
|
||||
@@ -954,6 +964,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
@@ -841,6 +844,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
GST_STATIC_PAD_TEMPLATE("mf_src", GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY);
|
||||
|
||||
struct media_source *object = heap_alloc_zero(sizeof(*object));
|
||||
@ -100,22 +114,22 @@ index 6190ac57e0e..5f203a946bc 100644
|
||||
unsigned int i;
|
||||
HRESULT hr;
|
||||
int ret;
|
||||
@@ -1043,6 +1054,25 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
@@ -928,6 +932,25 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
gst_sample_unref(preroll);
|
||||
}
|
||||
|
||||
+ /* init presentation descriptor */
|
||||
+
|
||||
+ descriptors = heap_alloc(object->stream_count * sizeof(IMFStreamDescriptor*));
|
||||
+ for (unsigned int i = 0; i < object->stream_count; i++)
|
||||
+ for (i = 0; i < object->stream_count; i++)
|
||||
+ {
|
||||
+ IMFMediaStream_GetStreamDescriptor(&object->streams[i]->IMFMediaStream_iface, &descriptors[i]);
|
||||
+ }
|
||||
+
|
||||
+ if (FAILED(MFCreatePresentationDescriptor(object->stream_count, descriptors, &object->pres_desc)))
|
||||
+ if (FAILED(hr = MFCreatePresentationDescriptor(object->stream_count, descriptors, &object->pres_desc)))
|
||||
+ goto fail;
|
||||
+
|
||||
+ for (unsigned int i = 0; i < object->stream_count; i++)
|
||||
+ for (i = 0; i < object->stream_count; i++)
|
||||
+ {
|
||||
+ IMFPresentationDescriptor_SelectStream(object->pres_desc, i);
|
||||
+ IMFStreamDescriptor_Release(descriptors[i]);
|
||||
@ -126,12 +140,11 @@ index 6190ac57e0e..5f203a946bc 100644
|
||||
object->state = SOURCE_STOPPED;
|
||||
|
||||
*out_media_source = object;
|
||||
@@ -1051,6 +1081,8 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
@@ -936,6 +959,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
fail:
|
||||
WARN("Failed to construct MFMediaSource, hr %#x.\n", hr);
|
||||
|
||||
+ if (descriptors)
|
||||
+ heap_free(descriptors);
|
||||
+ heap_free(descriptors);
|
||||
IMFMediaSource_Release(&object->IMFMediaSource_iface);
|
||||
return hr;
|
||||
}
|
@ -1,19 +1,21 @@
|
||||
From 94891a5e484b97577df09a4e6ef3106c79d2391a Mon Sep 17 00:00:00 2001
|
||||
From 747e873ecc739c3808629b8b16ae3cbf5e8a07d7 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 31 Mar 2020 15:10:03 -0500
|
||||
Date: Tue, 24 Mar 2020 16:15:35 -0500
|
||||
Subject: [PATCH] winegstreamer: Implement IMFMediaSource::Start.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/mfplat/tests/mfplat.c | 8 +-
|
||||
dlls/winegstreamer/media_source.c | 319 +++++++++++++++++++++++++++++-
|
||||
2 files changed, 317 insertions(+), 10 deletions(-)
|
||||
dlls/winegstreamer/gst_private.h | 1 +
|
||||
dlls/winegstreamer/media_source.c | 307 +++++++++++++++++++++++++++++-
|
||||
dlls/winegstreamer/mfplat.c | 125 ++++++++++++
|
||||
4 files changed, 433 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
|
||||
index 72d06e31880..e6a1694a11f 100644
|
||||
index 7491b53896f..ef9837c0a8a 100644
|
||||
--- a/dlls/mfplat/tests/mfplat.c
|
||||
+++ b/dlls/mfplat/tests/mfplat.c
|
||||
@@ -604,10 +604,7 @@ static void test_source_resolver(void)
|
||||
@@ -605,10 +605,7 @@ todo_wine
|
||||
|
||||
var.vt = VT_EMPTY;
|
||||
hr = IMFMediaSource_Start(mediasource, descriptor, &GUID_NULL, &var);
|
||||
@ -24,7 +26,7 @@ index 72d06e31880..e6a1694a11f 100644
|
||||
|
||||
get_event((IMFMediaEventGenerator *)mediasource, MENewStream, &var);
|
||||
ok(var.vt == VT_UNKNOWN, "Unexpected value type %u from MENewStream event.\n", var.vt);
|
||||
@@ -625,10 +622,13 @@ todo_wine
|
||||
@@ -626,10 +623,13 @@ todo_wine
|
||||
hr = IMFMediaStream_RequestSample(video_stream, NULL);
|
||||
if (i == sample_count)
|
||||
break;
|
||||
@ -38,7 +40,7 @@ index 72d06e31880..e6a1694a11f 100644
|
||||
|
||||
for (i = 0; i < sample_count; ++i)
|
||||
{
|
||||
@@ -666,11 +666,11 @@ todo_wine
|
||||
@@ -667,11 +667,11 @@ todo_wine
|
||||
|
||||
hr = IMFMediaStream_RequestSample(video_stream, NULL);
|
||||
ok(hr == MF_E_END_OF_STREAM, "Unexpected hr %#x.\n", hr);
|
||||
@ -51,20 +53,31 @@ index 72d06e31880..e6a1694a11f 100644
|
||||
IMFMediaTypeHandler_Release(handler);
|
||||
IMFPresentationDescriptor_Release(descriptor);
|
||||
|
||||
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/media_source.c b/dlls/winegstreamer/media_source.c
|
||||
index 5f203a946bc..d6ea8b52aca 100644
|
||||
index 9b2c2174318..70c5b47ba84 100644
|
||||
--- a/dlls/winegstreamer/media_source.c
|
||||
+++ b/dlls/winegstreamer/media_source.c
|
||||
@@ -55,14 +55,39 @@ struct media_stream
|
||||
@@ -55,14 +55,38 @@ struct media_stream
|
||||
{
|
||||
STREAM_INACTIVE,
|
||||
STREAM_SHUTDOWN,
|
||||
+ STREAM_RUNNING,
|
||||
} state;
|
||||
DWORD stream_id;
|
||||
+ BOOL eos;
|
||||
+};
|
||||
+
|
||||
};
|
||||
|
||||
+enum source_async_op
|
||||
+{
|
||||
+ SOURCE_ASYNC_START,
|
||||
@ -84,8 +97,8 @@ index 5f203a946bc..d6ea8b52aca 100644
|
||||
+ PROPVARIANT position;
|
||||
+ } start;
|
||||
+ } u;
|
||||
};
|
||||
|
||||
+};
|
||||
+
|
||||
struct media_source
|
||||
{
|
||||
IMFMediaSource IMFMediaSource_iface;
|
||||
@ -95,7 +108,7 @@ index 5f203a946bc..d6ea8b52aca 100644
|
||||
IMFMediaEventQueue *event_queue;
|
||||
IMFByteStream *byte_stream;
|
||||
struct media_stream **streams;
|
||||
@@ -76,6 +101,7 @@ struct media_source
|
||||
@@ -76,6 +100,7 @@ struct media_source
|
||||
{
|
||||
SOURCE_OPENING,
|
||||
SOURCE_STOPPED,
|
||||
@ -103,7 +116,7 @@ index 5f203a946bc..d6ea8b52aca 100644
|
||||
SOURCE_SHUTDOWN,
|
||||
} state;
|
||||
HANDLE no_more_pads_event;
|
||||
@@ -91,7 +117,265 @@ static inline struct media_source *impl_from_IMFMediaSource(IMFMediaSource *ifac
|
||||
@@ -91,7 +116,260 @@ static inline struct media_source *impl_from_IMFMediaSource(IMFMediaSource *ifac
|
||||
return CONTAINING_RECORD(iface, struct media_source, IMFMediaSource_iface);
|
||||
}
|
||||
|
||||
@ -214,11 +227,12 @@ index 5f203a946bc..d6ea8b52aca 100644
|
||||
+{
|
||||
+ ULONG sd_count;
|
||||
+ IMFStreamDescriptor *ret;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ if (FAILED(IMFPresentationDescriptor_GetStreamDescriptorCount(pres_desc, &sd_count)))
|
||||
+ return NULL;
|
||||
+
|
||||
+ for (unsigned int i = 0; i < sd_count; i++)
|
||||
+ for (i = 0; i < sd_count; i++)
|
||||
+ {
|
||||
+ DWORD stream_id;
|
||||
+
|
||||
@ -233,13 +247,16 @@ index 5f203a946bc..d6ea8b52aca 100644
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
+static HRESULT start_pipeline(struct media_source *source, struct source_async_command *command)
|
||||
+static void start_pipeline(struct media_source *source, struct source_async_command *command)
|
||||
+{
|
||||
+ PROPVARIANT *position = &command->u.start.position;
|
||||
+ BOOL seek_message = source->state != SOURCE_STOPPED && position->vt != VT_EMPTY;
|
||||
+ GstStateChangeReturn ret;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ gst_element_set_state(source->container, GST_STATE_PAUSED);
|
||||
+ assert(gst_element_get_state(source->container, NULL, NULL, -1) == GST_STATE_CHANGE_SUCCESS);
|
||||
+ ret = gst_element_get_state(source->container, NULL, NULL, -1);
|
||||
+ assert(ret == GST_STATE_CHANGE_SUCCESS);
|
||||
+
|
||||
+ /* seek to beginning on stop->play */
|
||||
+ if (source->state == SOURCE_STOPPED && position->vt == VT_EMPTY)
|
||||
@ -248,7 +265,7 @@ index 5f203a946bc..d6ea8b52aca 100644
|
||||
+ position->u.hVal.QuadPart = 0;
|
||||
+ }
|
||||
+
|
||||
+ for (unsigned int i = 0; i < source->stream_count; i++)
|
||||
+ for (i = 0; i < source->stream_count; i++)
|
||||
+ {
|
||||
+ struct media_stream *stream;
|
||||
+ IMFStreamDescriptor *sd;
|
||||
@ -259,7 +276,6 @@ index 5f203a946bc..d6ea8b52aca 100644
|
||||
+ DWORD stream_id;
|
||||
+ BOOL was_active;
|
||||
+ BOOL selected;
|
||||
+ BOOL changed_caps;
|
||||
+
|
||||
+ stream = source->streams[i];
|
||||
+
|
||||
@ -278,12 +294,10 @@ index 5f203a946bc..d6ea8b52aca 100644
|
||||
+ IMFMediaTypeHandler_GetCurrentMediaType(mth, ¤t_mt);
|
||||
+ current_caps = caps_from_mf_media_type(current_mt);
|
||||
+ g_object_get(stream->appsink, "caps", &prev_caps, NULL);
|
||||
+ changed_caps = !gst_caps_is_equal(prev_caps, current_caps);
|
||||
+
|
||||
+ if (changed_caps)
|
||||
+ if (!gst_caps_is_equal(prev_caps, current_caps))
|
||||
+ {
|
||||
+ g_object_set(stream->appsink, "caps", current_caps, NULL);
|
||||
+ GstEvent *reconfigure_event = gst_event_new_reconfigure();
|
||||
+ g_object_set(stream->appsink, "caps", current_caps, NULL);
|
||||
+ gst_pad_push_event(gst_element_get_static_pad(stream->appsink, "sink"), reconfigure_event);
|
||||
+ }
|
||||
+
|
||||
@ -293,24 +307,23 @@ index 5f203a946bc..d6ea8b52aca 100644
|
||||
+ IMFMediaTypeHandler_Release(mth);
|
||||
+ }
|
||||
+
|
||||
+ g_object_set(stream->appsink, "drop", !selected, NULL);
|
||||
+
|
||||
+ if (position->vt != VT_EMPTY)
|
||||
+ {
|
||||
+ GstEvent *seek_event = gst_event_new_seek(1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH,
|
||||
+ GST_SEEK_TYPE_SET, position->u.hVal.QuadPart / 100, GST_SEEK_TYPE_NONE, 0);
|
||||
+
|
||||
+ GstSample *preroll;
|
||||
+
|
||||
+ gst_pad_push_event(stream->my_sink, seek_event);
|
||||
+ gst_bus_poll(source->bus, GST_MESSAGE_RESET_TIME, -1);
|
||||
+
|
||||
+ stream->eos = FALSE;
|
||||
+ }
|
||||
+
|
||||
+ if (selected)
|
||||
+ {
|
||||
+ TRACE("Stream %u (%p) selected\n", i, stream);
|
||||
+ IMFMediaEventQueue_QueueEventParamUnk(source->event_queue,
|
||||
+ was_active ? MEUpdatedStream : MENewStream, &GUID_NULL,
|
||||
+ S_OK, (IUnknown*) &stream->IMFMediaStream_iface);
|
||||
+ was_active ? MEUpdatedStream : MENewStream, &GUID_NULL,
|
||||
+ S_OK, (IUnknown*) &stream->IMFMediaStream_iface);
|
||||
+
|
||||
+ IMFMediaEventQueue_QueueEventParamVar(stream->event_queue,
|
||||
+ seek_message ? MEStreamSeeked : MEStreamStarted, &GUID_NULL, S_OK, position);
|
||||
@ -324,9 +337,6 @@ index 5f203a946bc..d6ea8b52aca 100644
|
||||
+ source->state = SOURCE_RUNNING;
|
||||
+
|
||||
+ gst_element_set_state(source->container, GST_STATE_PLAYING);
|
||||
+ gst_element_get_state(source->container, NULL, NULL, -1);
|
||||
+
|
||||
+ return S_OK;
|
||||
+}
|
||||
+
|
||||
+static HRESULT WINAPI source_async_commands_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
|
||||
@ -348,8 +358,6 @@ index 5f203a946bc..d6ea8b52aca 100644
|
||||
+ case SOURCE_ASYNC_START:
|
||||
+ start_pipeline(source, command);
|
||||
+ break;
|
||||
+ default:
|
||||
+ ;
|
||||
+ }
|
||||
+
|
||||
+ IUnknown_Release(state);
|
||||
@ -370,18 +378,7 @@ index 5f203a946bc..d6ea8b52aca 100644
|
||||
GstBuffer **buf)
|
||||
{
|
||||
struct media_source *source = gst_pad_get_element_private(pad);
|
||||
@@ -240,8 +524,8 @@ GstBusSyncReply bus_watch(GstBus *bus, GstMessage *message, gpointer user)
|
||||
break;
|
||||
}
|
||||
|
||||
- gst_message_unref(message);
|
||||
- return GST_BUS_DROP;
|
||||
+ /* FIXME: drop messages and find a substitute for gst_bus_poll */
|
||||
+ return GST_BUS_PASS;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI media_stream_QueryInterface(IMFMediaStream *iface, REFIID riid, void **out)
|
||||
@@ -798,16 +1082,32 @@ static HRESULT WINAPI media_source_CreatePresentationDescriptor(IMFMediaSource *
|
||||
@@ -683,16 +961,30 @@ static HRESULT WINAPI media_source_CreatePresentationDescriptor(IMFMediaSource *
|
||||
}
|
||||
|
||||
static HRESULT WINAPI media_source_Start(IMFMediaSource *iface, IMFPresentationDescriptor *descriptor,
|
||||
@ -400,9 +397,7 @@ index 5f203a946bc..d6ea8b52aca 100644
|
||||
|
||||
- return E_NOTIMPL;
|
||||
+ if (!(IsEqualIID(time_format, &GUID_NULL)))
|
||||
+ {
|
||||
+ return MF_E_UNSUPPORTED_TIME_FORMAT;
|
||||
+ }
|
||||
+
|
||||
+ if (SUCCEEDED(hr = source_create_async_op(SOURCE_ASYNC_START, &command)))
|
||||
+ {
|
||||
@ -417,7 +412,7 @@ index 5f203a946bc..d6ea8b52aca 100644
|
||||
}
|
||||
|
||||
static HRESULT WINAPI media_source_Stop(IMFMediaSource *iface)
|
||||
@@ -876,6 +1176,9 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface)
|
||||
@@ -773,6 +1065,9 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface)
|
||||
if (source->no_more_pads_event)
|
||||
CloseHandle(source->no_more_pads_event);
|
||||
|
||||
@ -427,7 +422,7 @@ index 5f203a946bc..d6ea8b52aca 100644
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
@@ -973,6 +1276,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
@@ -853,6 +1148,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
object->IMFMediaSource_iface.lpVtbl = &IMFMediaSource_vtbl;
|
||||
@ -435,7 +430,7 @@ index 5f203a946bc..d6ea8b52aca 100644
|
||||
object->ref = 1;
|
||||
object->byte_stream = bytestream;
|
||||
IMFByteStream_AddRef(bytestream);
|
||||
@@ -981,6 +1285,9 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
@@ -861,6 +1157,9 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
if (FAILED(hr = MFCreateEventQueue(&object->event_queue)))
|
||||
goto fail;
|
||||
|
||||
@ -445,6 +440,139 @@ index 5f203a946bc..d6ea8b52aca 100644
|
||||
object->container = gst_bin_new(NULL);
|
||||
object->bus = gst_bus_new();
|
||||
gst_bus_set_sync_handler(object->bus, mf_src_bus_watch_wrapper, object, NULL);
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 2e8b0978648..43895c2cb5d 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -601,3 +601,128 @@ 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;
|
||||
+ UINT32 unused;
|
||||
+ GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
|
||||
+ GUID subtype_base;
|
||||
+ GstVideoInfo info;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ if (FAILED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size)))
|
||||
+ return NULL;
|
||||
+ width = frame_size >> 32;
|
||||
+ height = frame_size;
|
||||
+
|
||||
+ 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;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ subtype_base = subtype;
|
||||
+ subtype_base.Data1 = 0;
|
||||
+ if (format == GST_VIDEO_FORMAT_UNKNOWN && IsEqualGUID(&MFVideoFormat_Base, &subtype_base))
|
||||
+ format = gst_video_format_from_fourcc(subtype.Data1);
|
||||
+
|
||||
+ if (format == GST_VIDEO_FORMAT_UNKNOWN)
|
||||
+ {
|
||||
+ FIXME("Unrecognized format %s\n", debugstr_guid(&subtype));
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ gst_video_info_set_format(&info, format, width, height);
|
||||
+ output = gst_video_info_to_caps(&info);
|
||||
+
|
||||
+ 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 (SUCCEEDED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_RATE, &frame_rate)))
|
||||
+ gst_caps_set_simple(output, "framerate", GST_TYPE_FRACTION, frame_rate >> 32, (DWORD32) frame_rate, 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
|
||||
|
@ -1,21 +1,21 @@
|
||||
From d6e46ad311f773daed7d065c5c46f55c430a544c Mon Sep 17 00:00:00 2001
|
||||
From 274fb99e0ecfbec3ef7e6d1b93c4fd5ed2c68529 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Wed, 25 Mar 2020 10:43:03 -0500
|
||||
Date: Thu, 8 Oct 2020 16:39:53 -0500
|
||||
Subject: [PATCH] winegstreamer: Implement IMFMediaStream::RequestSample.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/mfplat/tests/mfplat.c | 4 --
|
||||
dlls/winegstreamer/gst_private.h | 1 +
|
||||
dlls/winegstreamer/media_source.c | 108 +++++++++++++++++++++++++++++-
|
||||
dlls/winegstreamer/mfplat.c | 90 +++++++++++++++++++++++++
|
||||
4 files changed, 198 insertions(+), 5 deletions(-)
|
||||
dlls/mfplat/tests/mfplat.c | 4 --
|
||||
dlls/winegstreamer/gst_private.h | 1 +
|
||||
dlls/winegstreamer/media_source.c | 92 ++++++++++++++++++++++++++++++-
|
||||
dlls/winegstreamer/mfplat.c | 69 +++++++++++++++++++++++
|
||||
4 files changed, 161 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c
|
||||
index e6a1694a11f..6dd2c3cbe96 100644
|
||||
index ef9837c0a8a..572cb8dec9a 100644
|
||||
--- a/dlls/mfplat/tests/mfplat.c
|
||||
+++ b/dlls/mfplat/tests/mfplat.c
|
||||
@@ -622,13 +622,10 @@ static void test_source_resolver(void)
|
||||
@@ -623,13 +623,10 @@ todo_wine
|
||||
hr = IMFMediaStream_RequestSample(video_stream, NULL);
|
||||
if (i == sample_count)
|
||||
break;
|
||||
@ -29,7 +29,7 @@ index e6a1694a11f..6dd2c3cbe96 100644
|
||||
|
||||
for (i = 0; i < sample_count; ++i)
|
||||
{
|
||||
@@ -669,7 +666,6 @@ todo_wine
|
||||
@@ -670,7 +667,6 @@ todo_wine
|
||||
|
||||
get_event((IMFMediaEventGenerator *)mediasource, MEEndOfPresentation, NULL);
|
||||
|
||||
@ -38,11 +38,11 @@ index e6a1694a11f..6dd2c3cbe96 100644
|
||||
IMFMediaTypeHandler_Release(handler);
|
||||
IMFPresentationDescriptor_Release(descriptor);
|
||||
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
|
||||
index 00e28f1d092..df1e643c3f6 100644
|
||||
index 07556802a51..ff5aff42482 100644
|
||||
--- a/dlls/winegstreamer/gst_private.h
|
||||
+++ b/dlls/winegstreamer/gst_private.h
|
||||
@@ -59,6 +59,7 @@ HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HI
|
||||
GstCaps *make_mf_compatible_caps(GstCaps *caps) DECLSPEC_HIDDEN;
|
||||
@@ -58,6 +58,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;
|
||||
+IMFSample *mf_sample_from_gst_buffer(GstBuffer *in) DECLSPEC_HIDDEN;
|
||||
@ -50,10 +50,16 @@ index 00e28f1d092..df1e643c3f6 100644
|
||||
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
|
||||
|
||||
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
|
||||
index d6ea8b52aca..31f90443ee4 100644
|
||||
index 70c5b47ba84..a67f1cb71d7 100644
|
||||
--- a/dlls/winegstreamer/media_source.c
|
||||
+++ b/dlls/winegstreamer/media_source.c
|
||||
@@ -64,6 +64,7 @@ struct media_stream
|
||||
@@ -58,11 +58,13 @@ struct media_stream
|
||||
STREAM_RUNNING,
|
||||
} state;
|
||||
DWORD stream_id;
|
||||
+ BOOL eos;
|
||||
};
|
||||
|
||||
enum source_async_op
|
||||
{
|
||||
SOURCE_ASYNC_START,
|
||||
@ -61,7 +67,7 @@ index d6ea8b52aca..31f90443ee4 100644
|
||||
};
|
||||
|
||||
struct source_async_command
|
||||
@@ -79,6 +80,11 @@ struct source_async_command
|
||||
@@ -78,6 +80,11 @@ struct source_async_command
|
||||
GUID format;
|
||||
PROPVARIANT position;
|
||||
} start;
|
||||
@ -73,16 +79,26 @@ index d6ea8b52aca..31f90443ee4 100644
|
||||
} u;
|
||||
};
|
||||
|
||||
@@ -338,6 +344,78 @@ static HRESULT start_pipeline(struct media_source *source, struct source_async_c
|
||||
return S_OK;
|
||||
@@ -311,6 +318,8 @@ static void start_pipeline(struct media_source *source, struct source_async_comm
|
||||
GstSample *preroll;
|
||||
|
||||
gst_pad_push_event(stream->my_sink, seek_event);
|
||||
+
|
||||
+ stream->eos = FALSE;
|
||||
}
|
||||
|
||||
if (selected)
|
||||
@@ -334,6 +343,59 @@ static void start_pipeline(struct media_source *source, struct source_async_comm
|
||||
gst_element_set_state(source->container, GST_STATE_PLAYING);
|
||||
}
|
||||
|
||||
+static void dispatch_end_of_presentation(struct media_source *source)
|
||||
+{
|
||||
+ PROPVARIANT empty = {.vt = VT_EMPTY};
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ /* A stream has ended, check whether all have */
|
||||
+ for (unsigned int i = 0; i < source->stream_count; i++)
|
||||
+ for (i = 0; i < source->stream_count; i++)
|
||||
+ {
|
||||
+ struct media_stream *stream = source->streams[i];
|
||||
+
|
||||
@ -93,7 +109,7 @@ index d6ea8b52aca..31f90443ee4 100644
|
||||
+ IMFMediaEventQueue_QueueEventParamVar(source->event_queue, MEEndOfPresentation, &GUID_NULL, S_OK, &empty);
|
||||
+}
|
||||
+
|
||||
+static HRESULT wait_on_sample(struct media_stream *stream, IUnknown *token)
|
||||
+static void wait_on_sample(struct media_stream *stream, IUnknown *token)
|
||||
+{
|
||||
+ PROPVARIANT empty_var = {.vt = VT_EMPTY};
|
||||
+ GstSample *gst_sample;
|
||||
@ -107,24 +123,7 @@ index d6ea8b52aca..31f90443ee4 100644
|
||||
+ {
|
||||
+ buffer = gst_sample_get_buffer(gst_sample);
|
||||
+
|
||||
+ if (TRACE_ON(mfplat))
|
||||
+ {
|
||||
+ const GstCaps *sample_caps = gst_sample_get_caps(gst_sample);
|
||||
+ const GstStructure *sample_info = gst_sample_get_info(gst_sample);
|
||||
+ if (sample_caps)
|
||||
+ {
|
||||
+ gchar *sample_caps_str = gst_caps_to_string(sample_caps);
|
||||
+ TRACE("sample caps %s\n", debugstr_a(sample_caps_str));
|
||||
+ g_free(sample_caps_str);
|
||||
+ }
|
||||
+ if (sample_info)
|
||||
+ {
|
||||
+ gchar *sample_info_str = gst_structure_to_string(sample_info);
|
||||
+ TRACE("sample info %s\n", debugstr_a(sample_info_str));
|
||||
+ g_free(sample_info_str);
|
||||
+ }
|
||||
+ TRACE("PTS = %lu DTS = %lu\n", GST_BUFFER_PTS(buffer), GST_BUFFER_DTS(buffer));
|
||||
+ }
|
||||
+ TRACE("PTS = %llu\n", (unsigned long long int) GST_BUFFER_PTS(buffer));
|
||||
+
|
||||
+ sample = mf_sample_from_gst_buffer(buffer);
|
||||
+ gst_sample_unref(gst_sample);
|
||||
@ -143,26 +142,23 @@ index d6ea8b52aca..31f90443ee4 100644
|
||||
+ IUnknown_Release(token);
|
||||
+ IMFMediaEventQueue_QueueEventParamVar(stream->event_queue, MEEndOfStream, &GUID_NULL, S_OK, &empty_var);
|
||||
+ dispatch_end_of_presentation(stream->parent_source);
|
||||
+ return S_OK;
|
||||
+ }
|
||||
+
|
||||
+ return S_OK;
|
||||
+}
|
||||
+
|
||||
static HRESULT WINAPI source_async_commands_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
|
||||
{
|
||||
struct media_source *source = impl_from_async_commands_callback_IMFAsyncCallback(iface);
|
||||
@@ -357,6 +435,9 @@ static HRESULT WINAPI source_async_commands_Invoke(IMFAsyncCallback *iface, IMFA
|
||||
@@ -353,6 +415,9 @@ static HRESULT WINAPI source_async_commands_Invoke(IMFAsyncCallback *iface, IMFA
|
||||
case SOURCE_ASYNC_START:
|
||||
start_pipeline(source, command);
|
||||
break;
|
||||
+ case SOURCE_ASYNC_REQUEST_SAMPLE:
|
||||
+ wait_on_sample(command->u.request_sample.stream, command->u.request_sample.token);
|
||||
+ break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
@@ -665,13 +746,37 @@ static HRESULT WINAPI media_stream_GetStreamDescriptor(IMFMediaStream* iface, IM
|
||||
|
||||
IUnknown_Release(state);
|
||||
@@ -640,13 +705,37 @@ static HRESULT WINAPI media_stream_GetStreamDescriptor(IMFMediaStream* iface, IM
|
||||
static HRESULT WINAPI media_stream_RequestSample(IMFMediaStream *iface, IUnknown *token)
|
||||
{
|
||||
struct media_stream *stream = impl_from_IMFMediaStream(iface);
|
||||
@ -193,7 +189,7 @@ index d6ea8b52aca..31f90443ee4 100644
|
||||
+ IUnknown_AddRef(token);
|
||||
+ command->u.request_sample.token = token;
|
||||
+
|
||||
+ /* Once pause support is added, this will need to into a stream queue, and synchronization will need to be added*/
|
||||
+ /* Once pause support is added, this will need to put into a stream queue, and synchronization will need to be added*/
|
||||
+ hr = MFPutWorkItem(stream->parent_source->async_commands_queue, &stream->parent_source->async_commands_callback, &command->IUnknown_iface);
|
||||
+ }
|
||||
+
|
||||
@ -201,7 +197,7 @@ index d6ea8b52aca..31f90443ee4 100644
|
||||
}
|
||||
|
||||
static const IMFMediaStreamVtbl media_stream_vtbl =
|
||||
@@ -843,6 +948,7 @@ static HRESULT new_media_stream(struct media_source *source, GstPad *pad, DWORD
|
||||
@@ -729,6 +818,7 @@ static HRESULT new_media_stream(struct media_source *source, GstPad *pad, DWORD
|
||||
object->stream_id = stream_id;
|
||||
|
||||
object->state = STREAM_INACTIVE;
|
||||
@ -210,10 +206,10 @@ index d6ea8b52aca..31f90443ee4 100644
|
||||
if (FAILED(hr = MFCreateEventQueue(&object->event_queue)))
|
||||
goto fail;
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 4b7a9760688..ce0c951ac0d 100644
|
||||
index 43895c2cb5d..e50fd2e04ab 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -1239,3 +1239,93 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
@@ -726,3 +726,72 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
FIXME("Unrecognized major type %s\n", debugstr_guid(&major_type));
|
||||
return NULL;
|
||||
}
|
||||
@ -229,83 +225,62 @@ index 4b7a9760688..ce0c951ac0d 100644
|
||||
+
|
||||
+IMFSample* mf_sample_from_gst_buffer(GstBuffer *gst_buffer)
|
||||
+{
|
||||
+ IMFSample *out = NULL;
|
||||
+ IMFMediaBuffer *mf_buffer = NULL;
|
||||
+ GstMapInfo map_info = {0};
|
||||
+ LONGLONG duration, time;
|
||||
+ int buffer_count;
|
||||
+ BYTE *mapped_buf = NULL;
|
||||
+ IMFSample *out = NULL;
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ if (FAILED(hr = MFCreateSample(&out)))
|
||||
+ goto fail;
|
||||
+ goto done;
|
||||
+
|
||||
+ duration = GST_BUFFER_DURATION(gst_buffer);
|
||||
+ time = GST_BUFFER_PTS(gst_buffer);
|
||||
+
|
||||
+ if (FAILED(IMFSample_SetSampleDuration(out, duration / 100)))
|
||||
+ goto fail;
|
||||
+ if (FAILED(hr = IMFSample_SetSampleDuration(out, duration / 100)))
|
||||
+ goto done;
|
||||
+
|
||||
+ if (FAILED(IMFSample_SetSampleTime(out, time / 100)))
|
||||
+ goto fail;
|
||||
+ if (FAILED(hr = IMFSample_SetSampleTime(out, time / 100)))
|
||||
+ goto done;
|
||||
+
|
||||
+ buffer_count = gst_buffer_n_memory(gst_buffer);
|
||||
+
|
||||
+ for (unsigned int i = 0; i < buffer_count; i++)
|
||||
+ if (!gst_buffer_map(gst_buffer, &map_info, GST_MAP_READ))
|
||||
+ {
|
||||
+ GstMemory *memory = gst_buffer_get_memory(gst_buffer, i);
|
||||
+ IMFMediaBuffer *mf_buffer = NULL;
|
||||
+ GstMapInfo map_info;
|
||||
+ BYTE *buf_data;
|
||||
+ hr = E_FAIL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ if (!memory)
|
||||
+ {
|
||||
+ hr = E_FAIL;
|
||||
+ goto loop_done;
|
||||
+ }
|
||||
+ if (FAILED(hr = MFCreateMemoryBuffer(map_info.maxsize, &mf_buffer)))
|
||||
+ goto done;
|
||||
+
|
||||
+ if (!(gst_memory_map(memory, &map_info, GST_MAP_READ)))
|
||||
+ {
|
||||
+ hr = E_FAIL;
|
||||
+ goto loop_done;
|
||||
+ }
|
||||
+ if (FAILED(hr = IMFMediaBuffer_Lock(mf_buffer, &mapped_buf, NULL, NULL)))
|
||||
+ goto done;
|
||||
+
|
||||
+ if (FAILED(hr = MFCreateMemoryBuffer(map_info.maxsize, &mf_buffer)))
|
||||
+ {
|
||||
+ gst_memory_unmap(memory, &map_info);
|
||||
+ goto loop_done;
|
||||
+ }
|
||||
+ memcpy(mapped_buf, map_info.data, map_info.size);
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaBuffer_Lock(mf_buffer, &buf_data, NULL, NULL)))
|
||||
+ {
|
||||
+ gst_memory_unmap(memory, &map_info);
|
||||
+ goto loop_done;
|
||||
+ }
|
||||
+ if (FAILED(hr = IMFMediaBuffer_Unlock(mf_buffer)))
|
||||
+ goto done;
|
||||
+
|
||||
+ memcpy(buf_data, map_info.data, map_info.size);
|
||||
+ if (FAILED(hr = IMFMediaBuffer_SetCurrentLength(mf_buffer, map_info.size)))
|
||||
+ goto done;
|
||||
+
|
||||
+ gst_memory_unmap(memory, &map_info);
|
||||
+ if (FAILED(hr = IMFSample_AddBuffer(out, mf_buffer)))
|
||||
+ goto done;
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaBuffer_Unlock(mf_buffer)))
|
||||
+ goto loop_done;
|
||||
+
|
||||
+ if (FAILED(hr = IMFMediaBuffer_SetCurrentLength(mf_buffer, map_info.size)))
|
||||
+ goto loop_done;
|
||||
+
|
||||
+ if (FAILED(hr = IMFSample_AddBuffer(out, mf_buffer)))
|
||||
+ goto loop_done;
|
||||
+
|
||||
+ loop_done:
|
||||
+ if (mf_buffer)
|
||||
+ IMFMediaBuffer_Release(mf_buffer);
|
||||
+ if (memory)
|
||||
+ gst_memory_unref(memory);
|
||||
+ if (FAILED(hr))
|
||||
+ goto fail;
|
||||
+done:
|
||||
+ if (mf_buffer)
|
||||
+ IMFMediaBuffer_Release(mf_buffer);
|
||||
+ if (map_info.data)
|
||||
+ gst_buffer_unmap(gst_buffer, &map_info);
|
||||
+ if (FAILED(hr))
|
||||
+ {
|
||||
+ ERR("Failed to copy IMFSample to GstBuffer, hr = %#x\n", hr);
|
||||
+ if (out)
|
||||
+ IMFSample_Release(out);
|
||||
+ out = NULL;
|
||||
+ }
|
||||
+
|
||||
+ return out;
|
||||
+ fail:
|
||||
+ ERR("Failed to copy IMFSample to GstBuffer, hr = %#x\n", hr);
|
||||
+ IMFSample_Release(out);
|
||||
+ return NULL;
|
||||
+}
|
||||
--
|
||||
2.28.0
|
@ -1,4 +1,4 @@
|
||||
From 073dde743ea2fe54e93c50ea24bb83c59adaddd1 Mon Sep 17 00:00:00 2001
|
||||
From 686c650852f1af5d9aa3197887325472210d2014 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 15 Sep 2020 14:25:26 -0500
|
||||
Subject: [PATCH] winegstreamer: Insert parser into pipeline to rectify type
|
||||
@ -7,12 +7,12 @@ Subject: [PATCH] winegstreamer: Insert parser into pipeline to rectify type
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/gst_private.h | 1 +
|
||||
dlls/winegstreamer/media_source.c | 149 +++++++++++++++++++++++++++++-
|
||||
dlls/winegstreamer/mfplat.c | 22 +++++
|
||||
3 files changed, 169 insertions(+), 3 deletions(-)
|
||||
dlls/winegstreamer/media_source.c | 111 ++++++++++++++++++++++++++++--
|
||||
dlls/winegstreamer/mfplat.c | 22 ++++++
|
||||
3 files changed, 130 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
|
||||
index 60b38a48f5a..7ec71d40800 100644
|
||||
index ff5aff42482..df1e643c3f6 100644
|
||||
--- a/dlls/winegstreamer/gst_private.h
|
||||
+++ b/dlls/winegstreamer/gst_private.h
|
||||
@@ -56,6 +56,7 @@ void start_dispatch_thread(void) DECLSPEC_HIDDEN;
|
||||
@ -21,16 +21,18 @@ index 60b38a48f5a..7ec71d40800 100644
|
||||
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;
|
||||
|
||||
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) 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 29947e1554f..92b4100f7bc 100644
|
||||
index a67f1cb71d7..c72ac064518 100644
|
||||
--- a/dlls/winegstreamer/media_source.c
|
||||
+++ b/dlls/winegstreamer/media_source.c
|
||||
@@ -403,6 +403,122 @@ static const IMFMediaStreamVtbl media_stream_vtbl =
|
||||
@@ -752,8 +752,17 @@ static const IMFMediaStreamVtbl media_stream_vtbl =
|
||||
media_stream_RequestSample
|
||||
};
|
||||
|
||||
-/* Setup a chain of elements which should hopefully allow transformations to any IMFMediaType
|
||||
- the user throws at us through gstreamer's caps negotiation. */
|
||||
+/* There are two paths this function can take.
|
||||
+ 1) In the first path, we are acting as a real media source, purely demuxing the input data,
|
||||
+ in whichever format it may be in, and passing it along. However, there can be different ways
|
||||
@ -42,43 +44,23 @@ index 29947e1554f..92b4100f7bc 100644
|
||||
+ 2) In the second path, we are dealing with x-raw output from decodebin. In this case, we just
|
||||
+ have to setup a chain of elements which should hopefully allow transformations to any IMFMediaType
|
||||
+ the user throws at us through gstreamer's caps negotiation.*/
|
||||
+static HRESULT media_stream_align_with_mf(struct media_stream *stream)
|
||||
+{
|
||||
+ GstCaps *source_caps = NULL;
|
||||
+ GstCaps *target_caps = NULL;
|
||||
+ HRESULT hr = E_FAIL;
|
||||
+
|
||||
+ if (!(source_caps = gst_pad_query_caps(stream->their_src, NULL)))
|
||||
+ goto done;
|
||||
+
|
||||
+ if (TRACE_ON(mfplat))
|
||||
+ {
|
||||
+ gchar *source_caps_str = gst_caps_to_string(source_caps);
|
||||
+ TRACE("source caps %s\n", debugstr_a(source_caps_str));
|
||||
+ g_free(source_caps_str);
|
||||
+ }
|
||||
+
|
||||
+ if (!strcmp(gst_structure_get_name(gst_caps_get_structure(source_caps, 0)), "video/x-raw") ||
|
||||
+ !strcmp(gst_structure_get_name(gst_caps_get_structure(source_caps, 0)), "audio/x-raw"))
|
||||
+ {
|
||||
+ stream->my_sink = gst_element_get_static_pad(stream->appsink, "sink");
|
||||
+ g_object_set(stream->appsink, "caps", source_caps, NULL);
|
||||
+ assert(gst_pad_link(stream->their_src, stream->my_sink) == GST_PAD_LINK_OK);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
static HRESULT media_stream_connect_to_sink(struct media_stream *stream)
|
||||
{
|
||||
GstCaps *source_caps = gst_pad_query_caps(stream->their_src, NULL);
|
||||
@@ -793,7 +802,68 @@ static HRESULT media_stream_connect_to_sink(struct media_stream *stream)
|
||||
}
|
||||
else
|
||||
{
|
||||
- stream->my_sink = gst_element_get_static_pad(stream->appsink, "sink");
|
||||
+ GstElement *parser = NULL;
|
||||
+ GstCaps *target_caps;
|
||||
+
|
||||
+ assert(gst_caps_is_fixed(source_caps));
|
||||
+
|
||||
+ if (!(target_caps = make_mf_compatible_caps(source_caps)))
|
||||
+ goto done;
|
||||
+
|
||||
+ if (TRACE_ON(mfplat))
|
||||
+ {
|
||||
+ gchar *target_caps_str = gst_caps_to_string(target_caps);
|
||||
+ TRACE("target caps %s\n", debugstr_a(target_caps_str));
|
||||
+ g_free(target_caps_str);
|
||||
+ gst_caps_unref(source_caps);
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ g_object_set(stream->appsink, "caps", target_caps, NULL);
|
||||
@ -97,13 +79,14 @@ index 29947e1554f..92b4100f7bc 100644
|
||||
+ parser_list_two = gst_element_factory_list_filter(parser_list_one, target_caps, GST_PAD_SRC, 0);
|
||||
+ gst_plugin_feature_list_free(parser_list_one);
|
||||
+ parser_list_one = parser_list_two;
|
||||
+ gst_caps_unref(target_caps);
|
||||
+
|
||||
+ if (!(g_list_length(parser_list_one)))
|
||||
+ {
|
||||
+ gst_plugin_feature_list_free(parser_list_one);
|
||||
+ ERR("Failed to find parser for stream\n");
|
||||
+ hr = E_FAIL;
|
||||
+ goto done;
|
||||
+ gst_caps_unref(source_caps);
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ parser_factory = g_list_first(parser_list_one)->data;
|
||||
@ -115,70 +98,56 @@ index 29947e1554f..92b4100f7bc 100644
|
||||
+
|
||||
+ if (!parser)
|
||||
+ {
|
||||
+ hr = E_FAIL;
|
||||
+ goto done;
|
||||
+ gst_caps_unref(source_caps);
|
||||
+ return E_FAIL;
|
||||
+ }
|
||||
+
|
||||
+ gst_bin_add(GST_BIN(stream->parent_source->container), parser);
|
||||
+
|
||||
+ assert(gst_pad_link(stream->their_src, gst_element_get_static_pad(parser, "sink")) == GST_PAD_LINK_OK);
|
||||
+
|
||||
+ assert(gst_element_link(parser, stream->appsink));
|
||||
+
|
||||
+ gst_element_sync_state_with_parent(parser);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ assert(gst_pad_link(stream->their_src, gst_element_get_static_pad(stream->appsink, "sink")) == GST_PAD_LINK_OK);
|
||||
+ gst_caps_unref(target_caps);
|
||||
+ }
|
||||
+
|
||||
+ stream->my_sink = gst_element_get_static_pad(parser ? parser : stream->appsink, "sink");
|
||||
+ }
|
||||
+
|
||||
+ hr = S_OK;
|
||||
+
|
||||
+ done:
|
||||
+ if (source_caps)
|
||||
+ gst_caps_unref(source_caps);
|
||||
+ if (target_caps)
|
||||
+ gst_caps_unref(target_caps);
|
||||
+
|
||||
+ return hr;
|
||||
+}
|
||||
+
|
||||
+
|
||||
static HRESULT new_media_stream(struct media_source *source, GstPad *pad, DWORD stream_id, struct media_stream **out_stream)
|
||||
{
|
||||
struct media_stream *object = heap_alloc_zero(sizeof(*object));
|
||||
@@ -433,8 +549,7 @@ static HRESULT new_media_stream(struct media_source *source, GstPad *pad, DWORD
|
||||
g_object_set(object->appsink, "sync", FALSE, NULL);
|
||||
g_object_set(object->appsink, "max-buffers", 5, NULL);
|
||||
}
|
||||
|
||||
- object->my_sink = gst_element_get_static_pad(object->appsink, "sink");
|
||||
- gst_pad_link(object->their_src, object->my_sink);
|
||||
+ media_stream_align_with_mf(object);
|
||||
|
||||
gst_element_sync_state_with_parent(object->appsink);
|
||||
|
||||
@@ -457,7 +572,16 @@ static HRESULT media_stream_init_desc(struct media_stream *stream)
|
||||
IMFMediaType *stream_type = NULL;
|
||||
HRESULT hr;
|
||||
|
||||
- stream_type = mf_media_type_from_caps(current_caps);
|
||||
+ if (strcmp(gst_structure_get_name(gst_caps_get_structure(current_caps, 0)), "video/x-raw") &&
|
||||
+ strcmp(gst_structure_get_name(gst_caps_get_structure(current_caps, 0)), "audio/x-raw"))
|
||||
if (gst_pad_link(stream->their_src, stream->my_sink) != GST_PAD_LINK_OK)
|
||||
@@ -903,7 +973,7 @@ static HRESULT media_stream_init_desc(struct media_stream *stream)
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
- else
|
||||
+ else if (!strcmp(major_type, "audio/x-raw"))
|
||||
{
|
||||
stream_type = mf_media_type_from_caps(current_caps);
|
||||
if (stream_type)
|
||||
@@ -912,6 +982,20 @@ static HRESULT media_stream_init_desc(struct media_stream *stream)
|
||||
type_count = 1;
|
||||
}
|
||||
}
|
||||
+ else
|
||||
+ {
|
||||
+ GstCaps *compatible_caps = make_mf_compatible_caps(current_caps);
|
||||
+ stream_type = mf_media_type_from_caps(compatible_caps);
|
||||
+ gst_caps_unref(compatible_caps);
|
||||
+ if (compatible_caps)
|
||||
+ {
|
||||
+ stream_type = mf_media_type_from_caps(compatible_caps);
|
||||
+ gst_caps_unref(compatible_caps);
|
||||
+ if (stream_type)
|
||||
+ {
|
||||
+ stream_types = &stream_type;
|
||||
+ type_count = 1;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+ stream_type = mf_media_type_from_caps(current_caps);
|
||||
+
|
||||
gst_caps_unref(current_caps);
|
||||
if (!stream_type)
|
||||
return E_FAIL;
|
||||
@@ -687,6 +811,23 @@ static const IMFMediaSourceVtbl IMFMediaSource_vtbl =
|
||||
|
||||
if (!type_count)
|
||||
{
|
||||
@@ -1178,6 +1262,23 @@ static const IMFMediaSourceVtbl IMFMediaSource_vtbl =
|
||||
media_source_Shutdown,
|
||||
};
|
||||
|
||||
@ -202,7 +171,7 @@ index 29947e1554f..92b4100f7bc 100644
|
||||
static void stream_added(GstElement *element, GstPad *pad, gpointer user)
|
||||
{
|
||||
struct media_source *source = user;
|
||||
@@ -787,6 +928,8 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
@@ -1283,6 +1384,8 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
|
||||
gst_bin_add(GST_BIN(object->container), object->decodebin);
|
||||
|
||||
@ -212,14 +181,13 @@ index 29947e1554f..92b4100f7bc 100644
|
||||
g_signal_connect(object->decodebin, "pad-removed", G_CALLBACK(mf_src_stream_removed_wrapper), object);
|
||||
g_signal_connect(object->decodebin, "no-more-pads", G_CALLBACK(mf_src_no_more_pads_wrapper), object);
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 2e8b0978648..a67cdef72fe 100644
|
||||
index e50fd2e04ab..6e1248ef0bd 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -601,3 +601,25 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
|
||||
|
||||
@@ -602,6 +602,28 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
|
||||
return media_type;
|
||||
}
|
||||
+
|
||||
|
||||
+GstCaps *make_mf_compatible_caps(GstCaps *caps)
|
||||
+{
|
||||
+ GstCaps *ret;
|
||||
@ -241,6 +209,10 @@ index 2e8b0978648..a67cdef72fe 100644
|
||||
+
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
{
|
||||
GUID major_type;
|
||||
--
|
||||
2.28.0
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 3a0e2a85e06e2026a430fe548374f36b9be7a53b Mon Sep 17 00:00:00 2001
|
||||
From b472ddc94d02fdb30fbf2e848abf544343bc78ae Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 24 Mar 2020 16:00:26 -0500
|
||||
Subject: [PATCH] winegstreamer: Translate H.264 caps to attributes.
|
||||
@ -9,7 +9,7 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 80 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index a67cdef72fe..97b02d85a5d 100644
|
||||
index 6e1248ef0bd..f23817cee73 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -26,6 +26,7 @@
|
@ -1,4 +1,4 @@
|
||||
From 3abc720777969b80c82c8e19215d765e4ddca913 Mon Sep 17 00:00:00 2001
|
||||
From 726d3d6d9e7d4c836f57d58d95a6135a4c35dda7 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 24 Mar 2020 16:01:20 -0500
|
||||
Subject: [PATCH] winegstreamer: Translate WMV caps to attributes.
|
||||
@ -9,7 +9,7 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 51 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 97b02d85a5d..1ef86a3cff5 100644
|
||||
index f23817cee73..44d27594509 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -457,6 +457,24 @@ uncompressed_video_formats[] =
|
@ -1,183 +0,0 @@
|
||||
From 04d17547828174ec264284752eb65b1b1e1b942d Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 24 Mar 2020 16:15:35 -0500
|
||||
Subject: [PATCH] winegstreamer: Introduce IMFMediaType -> GstCaps converter.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@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 7ec71d40800..00e28f1d092 100644
|
||||
--- a/dlls/winegstreamer/gst_private.h
|
||||
+++ b/dlls/winegstreamer/gst_private.h
|
||||
@@ -58,6 +58,7 @@ extern HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
|
||||
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;
|
||||
|
||||
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 4aedfea45e0..f0b611e7ef5 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -902,3 +902,152 @@ GstCaps *make_mf_compatible_caps(GstCaps *caps)
|
||||
|
||||
return ret;
|
||||
}
|
||||
+
|
||||
+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
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 0a7b4fe24117d2c9e782b046819ffa7d3e646ae4 Mon Sep 17 00:00:00 2001
|
||||
From d6e9efab74da3fc8d64b84d60b043d663e09b0ad Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 24 Mar 2020 16:02:27 -0500
|
||||
Subject: [PATCH] winegstreamer: Translate AAC caps to attributes.
|
||||
@ -9,7 +9,7 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 108 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 1ef86a3cff5..9239cf9eff9 100644
|
||||
index 44d27594509..4fa37ab66d4 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -457,6 +457,15 @@ uncompressed_video_formats[] =
|
@ -1,4 +1,4 @@
|
||||
From ae279be0b4841c998dfa916f61f5bd7507190938 Mon Sep 17 00:00:00 2001
|
||||
From 16c6008bab9df24367556daa7c3f8e82a3cd1336 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Wed, 25 Mar 2020 13:36:19 -0500
|
||||
Subject: [PATCH] winegstreamer: Translate MPEG-4 Section-2 caps to attributes.
|
||||
@ -9,7 +9,7 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 16 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 9239cf9eff9..4fde3a8a7fb 100644
|
||||
index 4fa37ab66d4..b3bac362cf6 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -650,6 +650,22 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
|
@ -1,4 +1,4 @@
|
||||
From 2010fec0d85988d7a0b7aaadd6438e1d5c727e4a Mon Sep 17 00:00:00 2001
|
||||
From b85bb396862a124034c138c52c3da5511c3a82da Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 12 May 2020 17:05:41 -0500
|
||||
Subject: [PATCH] winegstreamer: Translate WMA caps to attributes.
|
||||
@ -9,7 +9,7 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 24 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 4fde3a8a7fb..4aedfea45e0 100644
|
||||
index b3bac362cf6..dea56839647 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -830,6 +830,30 @@ IMFMediaType *mf_media_type_from_caps(const GstCaps *caps)
|
@ -1,23 +1,36 @@
|
||||
From 3e0c22f47b91d130d1e136fa3282cbed1f275f0a Mon Sep 17 00:00:00 2001
|
||||
From 9fd2109de96d5804403fa21ea61bb1a429b72090 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 24 Mar 2020 16:18:40 -0500
|
||||
Subject: [PATCH] winegstreamer: Translate H.264 attributes to caps.
|
||||
|
||||
Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
---
|
||||
dlls/winegstreamer/mfplat.c | 48 +++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 48 insertions(+)
|
||||
dlls/winegstreamer/mfplat.c | 90 +++++++++++++++++++++++++++++--------
|
||||
1 file changed, 71 insertions(+), 19 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index f0b611e7ef5..7370ae26f4f 100644
|
||||
index dea56839647..8461e8af01f 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -972,6 +972,54 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
}
|
||||
@@ -919,10 +919,6 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
UINT64 frame_rate = 0, frame_size = 0;
|
||||
DWORD width, height;
|
||||
UINT32 unused;
|
||||
- GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
|
||||
- GUID subtype_base;
|
||||
- GstVideoInfo info;
|
||||
- unsigned int i;
|
||||
|
||||
}
|
||||
+ else if (IsEqualGUID(&subtype, &MFVideoFormat_H264))
|
||||
+ {
|
||||
if (FAILED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size)))
|
||||
return NULL;
|
||||
@@ -931,28 +927,84 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
|
||||
output = gst_caps_new_empty_simple("video/x-raw");
|
||||
|
||||
- for (i = 0; i < ARRAY_SIZE(uncompressed_video_formats); i++)
|
||||
+ if (IsEqualGUID(&subtype, &MFVideoFormat_H264))
|
||||
{
|
||||
- if (IsEqualGUID(uncompressed_video_formats[i].subtype, &subtype))
|
||||
+ enum eAVEncH264VProfile h264_profile;
|
||||
+ enum eAVEncH264VLevel h264_level;
|
||||
+ output = gst_caps_new_empty_simple("video/x-h264");
|
||||
@ -38,7 +51,9 @@ index f0b611e7ef5..7370ae26f4f 100644
|
||||
+ gst_caps_set_simple(output, "profile", G_TYPE_STRING, profile, NULL);
|
||||
+ }
|
||||
+ if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_MPEG2_LEVEL, &h264_level)))
|
||||
+ {
|
||||
{
|
||||
- format = uncompressed_video_formats[i].format;
|
||||
- break;
|
||||
+ const char *level = NULL;
|
||||
+ switch (h264_level)
|
||||
+ {
|
||||
@ -62,11 +77,52 @@ index f0b611e7ef5..7370ae26f4f 100644
|
||||
+ }
|
||||
+ if (level)
|
||||
+ gst_caps_set_simple(output, "level", G_TYPE_STRING, level, NULL);
|
||||
}
|
||||
}
|
||||
+ else
|
||||
+ {
|
||||
+ GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
|
||||
+ GUID subtype_base;
|
||||
+ GstVideoInfo info;
|
||||
+ unsigned int i;
|
||||
|
||||
- subtype_base = subtype;
|
||||
- subtype_base.Data1 = 0;
|
||||
- if (format == GST_VIDEO_FORMAT_UNKNOWN && IsEqualGUID(&MFVideoFormat_Base, &subtype_base))
|
||||
- format = gst_video_format_from_fourcc(subtype.Data1);
|
||||
+ 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)
|
||||
- {
|
||||
- FIXME("Unrecognized format %s\n", debugstr_guid(&subtype));
|
||||
- return NULL;
|
||||
- }
|
||||
+ subtype_base = subtype;
|
||||
+ subtype_base.Data1 = 0;
|
||||
+ if (format == GST_VIDEO_FORMAT_UNKNOWN && IsEqualGUID(&MFVideoFormat_Base, &subtype_base))
|
||||
+ format = gst_video_format_from_fourcc(subtype.Data1);
|
||||
|
||||
- gst_video_info_set_format(&info, format, width, height);
|
||||
- output = gst_video_info_to_caps(&info);
|
||||
+ if (format == GST_VIDEO_FORMAT_UNKNOWN)
|
||||
+ {
|
||||
+ FIXME("Unrecognized format %s\n", debugstr_guid(&subtype));
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ 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)
|
||||
{
|
||||
--
|
||||
2.28.0
|
||||
|
@ -1,4 +1,4 @@
|
||||
From dc5b390262d808615e4b49eb86286d2f6a6f41b1 Mon Sep 17 00:00:00 2001
|
||||
From d71b47eeac4b775c12c0670340559e57b683569d Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 24 Mar 2020 16:20:17 -0500
|
||||
Subject: [PATCH] winegstreamer: Translate WMV attributes to caps.
|
||||
@ -9,7 +9,7 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 51 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 7370ae26f4f..5779f81ce39 100644
|
||||
index 8461e8af01f..9b495d52659 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -903,6 +903,21 @@ GstCaps *make_mf_compatible_caps(GstCaps *caps)
|
||||
@ -34,7 +34,7 @@ index 7370ae26f4f..5779f81ce39 100644
|
||||
GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
{
|
||||
GUID major_type;
|
||||
@@ -1020,6 +1035,42 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
@@ -975,6 +990,42 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
gst_caps_set_simple(output, "level", G_TYPE_STRING, level, NULL);
|
||||
}
|
||||
}
|
||||
@ -74,9 +74,9 @@ index 7370ae26f4f..5779f81ce39 100644
|
||||
+
|
||||
+ user_data_to_codec_data(type, output);
|
||||
+ }
|
||||
else {
|
||||
FIXME("Unrecognized subtype %s\n", debugstr_guid(&subtype));
|
||||
return NULL;
|
||||
else
|
||||
{
|
||||
GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
|
||||
--
|
||||
2.28.0
|
||||
|
@ -1,4 +1,4 @@
|
||||
From f710ed4264cc6fb8c9ad1ffe15345c24e2d72aef Mon Sep 17 00:00:00 2001
|
||||
From 52eb35e32aecd3e1cae54109580495a8502dca45 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 21 Apr 2020 10:31:02 -0500
|
||||
Subject: [PATCH] winegstreamer: Translate AAC attributes to caps.
|
||||
@ -9,10 +9,10 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 66 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 5779f81ce39..58d23a9ac15 100644
|
||||
index 9b495d52659..9b75a709168 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -1120,6 +1120,72 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
@@ -1100,6 +1100,72 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
return NULL;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
From 7b3b63b25476f97aa1aad6636df47d6f540a52b3 Mon Sep 17 00:00:00 2001
|
||||
From fea795145aa7b64bbdc99a79c162226d1caa1c77 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Mon, 11 May 2020 16:03:09 -0500
|
||||
Subject: [PATCH] winegstreamer: Translate MPEG-4 Section-2 attributes to caps.
|
||||
@ -9,10 +9,10 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 8 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index 58d23a9ac15..a6230121cbf 100644
|
||||
index 9b75a709168..bd2a0ed1cb2 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -1071,6 +1071,14 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
@@ -1026,6 +1026,14 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
|
||||
user_data_to_codec_data(type, output);
|
||||
}
|
||||
@ -24,9 +24,9 @@ index 58d23a9ac15..a6230121cbf 100644
|
||||
+
|
||||
+ user_data_to_codec_data(type, output);
|
||||
+ }
|
||||
else {
|
||||
FIXME("Unrecognized subtype %s\n", debugstr_guid(&subtype));
|
||||
return NULL;
|
||||
else
|
||||
{
|
||||
GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
|
||||
--
|
||||
2.28.0
|
||||
|
@ -1,4 +1,4 @@
|
||||
From a8f54c1e644fcb185d3a6e3fc7b3e5e79a8b17d8 Mon Sep 17 00:00:00 2001
|
||||
From b96411942630ad39796166ebb615871dd0c8f082 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 12 May 2020 17:05:59 -0500
|
||||
Subject: [PATCH] winegstreamer: Translate WMA attributes to caps.
|
||||
@ -9,10 +9,10 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 15 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
|
||||
index a6230121cbf..4b7a9760688 100644
|
||||
index bd2a0ed1cb2..ac1fa67da6e 100644
|
||||
--- a/dlls/winegstreamer/mfplat.c
|
||||
+++ b/dlls/winegstreamer/mfplat.c
|
||||
@@ -1194,6 +1194,21 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
@@ -1174,6 +1174,21 @@ GstCaps *caps_from_mf_media_type(IMFMediaType *type)
|
||||
CoTaskMemFree(user_data);
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
From d3687d998fc5cc3ef11d53554e42c591905ffae2 Mon Sep 17 00:00:00 2001
|
||||
From e67fd844390a2c32e96a6bfdc0699f34df60480c Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 31 Mar 2020 15:15:07 -0500
|
||||
Subject: [PATCH] winegstreamer: Implement IMFMediaSource::GetCharacteristics.
|
||||
@ -9,10 +9,10 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
|
||||
index 31f90443ee4..536f0e5e140 100644
|
||||
index c72ac064518..2d00ca7e901 100644
|
||||
--- a/dlls/winegstreamer/media_source.c
|
||||
+++ b/dlls/winegstreamer/media_source.c
|
||||
@@ -1160,12 +1160,14 @@ static HRESULT WINAPI media_source_GetCharacteristics(IMFMediaSource *iface, DWO
|
||||
@@ -1114,12 +1114,14 @@ static HRESULT WINAPI media_source_GetCharacteristics(IMFMediaSource *iface, DWO
|
||||
{
|
||||
struct media_source *source = impl_from_IMFMediaSource(iface);
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
From 96232a45c5c32781ace6d14196e5c88603ad831f Mon Sep 17 00:00:00 2001
|
||||
From 541159bd92669732b4d7fce1cc3eda302ebdbfd8 Mon Sep 17 00:00:00 2001
|
||||
From: Derek Lesho <dlesho@codeweavers.com>
|
||||
Date: Tue, 31 Mar 2020 15:15:50 -0500
|
||||
Subject: [PATCH] winegstreamer: Calculate the MF_PD_DURATION of the media
|
||||
@ -10,10 +10,10 @@ Signed-off-by: Derek Lesho <dlesho@codeweavers.com>
|
||||
1 file changed, 40 insertions(+)
|
||||
|
||||
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
|
||||
index 536f0e5e140..ff6b7c8eac9 100644
|
||||
index 2d00ca7e901..e1b018b74ce 100644
|
||||
--- a/dlls/winegstreamer/media_source.c
|
||||
+++ b/dlls/winegstreamer/media_source.c
|
||||
@@ -1488,6 +1488,46 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
@@ -1445,6 +1445,46 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_
|
||||
heap_free(descriptors);
|
||||
descriptors = NULL;
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user