From 76a479203be67818473eb50bfa03afea20ca8859 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Tue, 29 Sep 2020 15:52:53 -0500 Subject: [PATCH] Rebase against 23c6dd55b8c983ec88cada0a6d6c75ee9cd93976. --- patches/bcrypt-ECDHSecretAgreement/definition | 5 +- ...-to-fail-if-we-don-t-support-vertice.patch | 33 - patches/d3dx9_36-Optimize_Inplace/definition | 1 - ...d-a-GstPad-wrapping-the-media-source.patch | 394 ------------ ...e-decodebin-to-initialize-media-stre.patch | 597 ------------------ ...plement-IMFMediaStream-GetStreamDesc.patch | 381 ----------- patches/mfplat-streaming-support/definition | 1 + patches/patchinstall.sh | 113 +--- staging/upstream-commit | 2 +- 9 files changed, 7 insertions(+), 1520 deletions(-) delete mode 100644 patches/d3dx9_36-Optimize_Inplace/0001-d3dx9_36-No-need-to-fail-if-we-don-t-support-vertice.patch delete mode 100644 patches/d3dx9_36-Optimize_Inplace/definition delete mode 100644 patches/mfplat-streaming-support/0001-winegstreamer-Add-a-GstPad-wrapping-the-media-source.patch delete mode 100644 patches/mfplat-streaming-support/0002-winegstreamer-Use-decodebin-to-initialize-media-stre.patch delete mode 100644 patches/mfplat-streaming-support/0003-winegstreamer-Implement-IMFMediaStream-GetStreamDesc.patch diff --git a/patches/bcrypt-ECDHSecretAgreement/definition b/patches/bcrypt-ECDHSecretAgreement/definition index f55871fe..25c47b4f 100644 --- a/patches/bcrypt-ECDHSecretAgreement/definition +++ b/patches/bcrypt-ECDHSecretAgreement/definition @@ -1,2 +1,5 @@ Fixes: [47699] Multiple games fail to connect to online services (missing BCryptSecretAgreement / BCryptDeriveKey implementation) - +# Needs to be moved to the unix lib, but that's a nontrivial amount of work, and +# using gcrypt is the wrong way forward (we should expose the missing APIs from +# gnutls instead). +Disabled: true diff --git a/patches/d3dx9_36-Optimize_Inplace/0001-d3dx9_36-No-need-to-fail-if-we-don-t-support-vertice.patch b/patches/d3dx9_36-Optimize_Inplace/0001-d3dx9_36-No-need-to-fail-if-we-don-t-support-vertice.patch deleted file mode 100644 index 733cb0db..00000000 --- a/patches/d3dx9_36-Optimize_Inplace/0001-d3dx9_36-No-need-to-fail-if-we-don-t-support-vertice.patch +++ /dev/null @@ -1,33 +0,0 @@ -From d037faddfa629e54b5ba13d57f2e4c185de2a555 Mon Sep 17 00:00:00 2001 -From: Christian Costa -Date: Tue, 4 Nov 2014 22:25:58 +0100 -Subject: d3dx9_36: No need to fail if we don't support vertices reordering in - D3DXMESHOPT_ATTRSORT - -A non optimized mesh does not prevent rendering as long as we return valid data to the application. -In our case we provided an identity remapping array when no vertices reordering is done. - -Avencast demo works perfectly well (using native effects functions). ---- - dlls/d3dx9_36/mesh.c | 4 ---- - 1 file changed, 4 deletions(-) - -diff --git a/dlls/d3dx9_36/mesh.c b/dlls/d3dx9_36/mesh.c -index 6f268f2..b15e033 100644 ---- a/dlls/d3dx9_36/mesh.c -+++ b/dlls/d3dx9_36/mesh.c -@@ -1700,11 +1700,7 @@ static HRESULT WINAPI d3dx9_mesh_OptimizeInplace(ID3DXMesh *iface, DWORD flags, - if (FAILED(hr)) goto cleanup; - } else if (flags & D3DXMESHOPT_ATTRSORT) { - if (!(flags & D3DXMESHOPT_IGNOREVERTS)) -- { - FIXME("D3DXMESHOPT_ATTRSORT vertex reordering not implemented.\n"); -- hr = E_NOTIMPL; -- goto cleanup; -- } - - hr = iface->lpVtbl->LockAttributeBuffer(iface, 0, &attrib_buffer); - if (FAILED(hr)) goto cleanup; --- -2.1.3 - diff --git a/patches/d3dx9_36-Optimize_Inplace/definition b/patches/d3dx9_36-Optimize_Inplace/definition deleted file mode 100644 index 3c2f9978..00000000 --- a/patches/d3dx9_36-Optimize_Inplace/definition +++ /dev/null @@ -1 +0,0 @@ -Fixes: [48529] Avencast fails to launch diff --git a/patches/mfplat-streaming-support/0001-winegstreamer-Add-a-GstPad-wrapping-the-media-source.patch b/patches/mfplat-streaming-support/0001-winegstreamer-Add-a-GstPad-wrapping-the-media-source.patch deleted file mode 100644 index ccbda270..00000000 --- a/patches/mfplat-streaming-support/0001-winegstreamer-Add-a-GstPad-wrapping-the-media-source.patch +++ /dev/null @@ -1,394 +0,0 @@ -From 76ebf639f8c353cba828c0dfb26fdc0e01318098 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Mon, 30 Mar 2020 14:19:35 -0500 -Subject: [PATCH] winegstreamer: Add a GstPad wrapping the media source's - bytestream. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/gst_cbs.c | 58 +++++++++ - dlls/winegstreamer/gst_cbs.h | 12 +- - dlls/winegstreamer/main.c | 3 + - dlls/winegstreamer/media_source.c | 189 +++++++++++++++++++++++++++++- - 4 files changed, 258 insertions(+), 4 deletions(-) - -diff --git a/dlls/winegstreamer/gst_cbs.c b/dlls/winegstreamer/gst_cbs.c -index bf7103b1606..12b53bc5d68 100644 ---- a/dlls/winegstreamer/gst_cbs.c -+++ b/dlls/winegstreamer/gst_cbs.c -@@ -49,6 +49,8 @@ static void CALLBACK perform_cb(TP_CALLBACK_INSTANCE *instance, void *user) - - if (cbdata->type < GSTDEMUX_MAX) - perform_cb_gstdemux(cbdata); -+ else if (cbdata->type < MEDIA_SOURCE_MAX) -+ perform_cb_media_source(cbdata); - - pthread_mutex_lock(&cbdata->lock); - cbdata->finished = 1; -@@ -301,3 +303,59 @@ gboolean query_sink_wrapper(GstPad *pad, GstObject *parent, GstQuery *query) - - return cbdata.u.query_sink_data.ret; - } -+ -+GstFlowReturn bytestream_wrapper_pull_wrapper(GstPad *pad, GstObject *parent, guint64 ofs, guint len, -+ GstBuffer **buf) -+{ -+ struct cb_data cbdata = { BYTESTREAM_WRAPPER_PULL }; -+ -+ cbdata.u.getrange_data.pad = pad; -+ cbdata.u.getrange_data.parent = parent; -+ cbdata.u.getrange_data.ofs = ofs; -+ cbdata.u.getrange_data.len = len; -+ cbdata.u.getrange_data.buf = buf; -+ -+ call_cb(&cbdata); -+ -+ return cbdata.u.getrange_data.ret; -+} -+ -+gboolean bytestream_query_wrapper(GstPad *pad, GstObject *parent, GstQuery *query) -+{ -+ struct cb_data cbdata = { BYTESTREAM_QUERY }; -+ -+ cbdata.u.query_function_data.pad = pad; -+ cbdata.u.query_function_data.parent = parent; -+ cbdata.u.query_function_data.query = query; -+ -+ call_cb(&cbdata); -+ -+ return cbdata.u.query_function_data.ret; -+} -+ -+gboolean bytestream_pad_mode_activate_wrapper(GstPad *pad, GstObject *parent, GstPadMode mode, gboolean activate) -+{ -+ struct cb_data cbdata = { BYTESTREAM_PAD_MODE_ACTIVATE }; -+ -+ cbdata.u.activate_mode_data.pad = pad; -+ cbdata.u.activate_mode_data.parent = parent; -+ cbdata.u.activate_mode_data.mode = mode; -+ cbdata.u.activate_mode_data.activate = activate; -+ -+ call_cb(&cbdata); -+ -+ return cbdata.u.activate_mode_data.ret; -+} -+ -+gboolean bytestream_pad_event_process_wrapper(GstPad *pad, GstObject *parent, GstEvent *event) -+{ -+ struct cb_data cbdata = { BYTESTREAM_PAD_EVENT_PROCESS }; -+ -+ cbdata.u.event_src_data.pad = pad; -+ cbdata.u.event_src_data.parent = parent; -+ cbdata.u.event_src_data.event = event; -+ -+ call_cb(&cbdata); -+ -+ return cbdata.u.event_src_data.ret; -+} -diff --git a/dlls/winegstreamer/gst_cbs.h b/dlls/winegstreamer/gst_cbs.h -index 4725f23ad1a..3459a9ef8ee 100644 ---- a/dlls/winegstreamer/gst_cbs.h -+++ b/dlls/winegstreamer/gst_cbs.h -@@ -43,7 +43,12 @@ enum CB_TYPE { - AUTOPLUG_BLACKLIST, - UNKNOWN_TYPE, - QUERY_SINK, -- GSTDEMUX_MAX -+ GSTDEMUX_MAX, -+ BYTESTREAM_WRAPPER_PULL, -+ BYTESTREAM_QUERY, -+ BYTESTREAM_PAD_MODE_ACTIVATE, -+ BYTESTREAM_PAD_EVENT_PROCESS, -+ MEDIA_SOURCE_MAX, - }; - - struct cb_data { -@@ -138,6 +143,7 @@ struct cb_data { - - void mark_wine_thread(void) DECLSPEC_HIDDEN; - void perform_cb_gstdemux(struct cb_data *data) DECLSPEC_HIDDEN; -+void perform_cb_media_source(struct cb_data *data) DECLSPEC_HIDDEN; - - GstBusSyncReply watch_bus_wrapper(GstBus *bus, GstMessage *msg, gpointer user) DECLSPEC_HIDDEN; - void existing_new_pad_wrapper(GstElement *bin, GstPad *pad, gpointer user) DECLSPEC_HIDDEN; -@@ -154,5 +160,9 @@ GstAutoplugSelectResult autoplug_blacklist_wrapper(GstElement *bin, GstPad *pad, - void unknown_type_wrapper(GstElement *bin, GstPad *pad, GstCaps *caps, gpointer user) DECLSPEC_HIDDEN; - void Gstreamer_transform_pad_added_wrapper(GstElement *filter, GstPad *pad, gpointer user) DECLSPEC_HIDDEN; - gboolean query_sink_wrapper(GstPad *pad, GstObject *parent, GstQuery *query) DECLSPEC_HIDDEN; -+GstFlowReturn bytestream_wrapper_pull_wrapper(GstPad *pad, GstObject *parent, guint64 ofs, guint len, GstBuffer **buf) DECLSPEC_HIDDEN; -+gboolean bytestream_query_wrapper(GstPad *pad, GstObject *parent, GstQuery *query) DECLSPEC_HIDDEN; -+gboolean bytestream_pad_mode_activate_wrapper(GstPad *pad, GstObject *parent, GstPadMode mode, gboolean activate) DECLSPEC_HIDDEN; -+gboolean bytestream_pad_event_process_wrapper(GstPad *pad, GstObject *parent, GstEvent *event) DECLSPEC_HIDDEN; - - #endif -diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c -index 2872710b3e2..4ca371d58bd 100644 ---- a/dlls/winegstreamer/main.c -+++ b/dlls/winegstreamer/main.c -@@ -146,6 +146,9 @@ HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **out) - - TRACE("clsid %s, iid %s, out %p.\n", debugstr_guid(clsid), debugstr_guid(iid), out); - -+ if (!init_gstreamer()) -+ return CLASS_E_CLASSNOTAVAILABLE; -+ - if (SUCCEEDED(hr = mfplat_get_class_object(clsid, iid, out))) - return hr; - -diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index f365c8a1827..1accf55c6a2 100644 ---- a/dlls/winegstreamer/media_source.c -+++ b/dlls/winegstreamer/media_source.c -@@ -17,9 +17,15 @@ - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -+#include "config.h" -+ -+#include -+ - #include "gst_private.h" -+#include "gst_cbs.h" - - #include -+#include - - #define COBJMACROS - #define NONAMELESSUNION -@@ -27,6 +33,7 @@ - #include "mfapi.h" - #include "mferror.h" - #include "mfidl.h" -+#include "mfobjects.h" - - #include "wine/debug.h" - #include "wine/heap.h" -@@ -39,6 +46,8 @@ struct media_source - IMFMediaSource IMFMediaSource_iface; - LONG ref; - IMFMediaEventQueue *event_queue; -+ IMFByteStream *byte_stream; -+ GstPad *my_src; - enum - { - SOURCE_OPENING, -@@ -52,6 +61,127 @@ static inline struct media_source *impl_from_IMFMediaSource(IMFMediaSource *ifac - return CONTAINING_RECORD(iface, struct media_source, IMFMediaSource_iface); - } - -+static GstFlowReturn bytestream_wrapper_pull(GstPad *pad, GstObject *parent, guint64 ofs, guint len, -+ GstBuffer **buf) -+{ -+ struct media_source *source = gst_pad_get_element_private(pad); -+ IMFByteStream *byte_stream = source->byte_stream; -+ ULONG bytes_read; -+ GstMapInfo info; -+ BOOL is_eof; -+ HRESULT hr; -+ -+ TRACE("requesting %u bytes at %s from source %p into buffer %p\n", len, wine_dbgstr_longlong(ofs), source, *buf); -+ -+ if (ofs != GST_BUFFER_OFFSET_NONE) -+ { -+ if (FAILED(IMFByteStream_SetCurrentPosition(byte_stream, ofs))) -+ return GST_FLOW_ERROR; -+ } -+ -+ if (FAILED(IMFByteStream_IsEndOfStream(byte_stream, &is_eof))) -+ return GST_FLOW_ERROR; -+ if (is_eof) -+ return GST_FLOW_EOS; -+ -+ if (!(*buf)) -+ *buf = gst_buffer_new_and_alloc(len); -+ gst_buffer_map(*buf, &info, GST_MAP_WRITE); -+ hr = IMFByteStream_Read(byte_stream, info.data, len, &bytes_read); -+ gst_buffer_unmap(*buf, &info); -+ -+ gst_buffer_set_size(*buf, bytes_read); -+ -+ if (FAILED(hr)) -+ return GST_FLOW_ERROR; -+ return GST_FLOW_OK; -+} -+ -+static gboolean bytestream_query(GstPad *pad, GstObject *parent, GstQuery *query) -+{ -+ struct media_source *source = gst_pad_get_element_private(pad); -+ GstFormat format; -+ QWORD bytestream_len; -+ -+ TRACE("GStreamer queries source %p for %s\n", source, GST_QUERY_TYPE_NAME(query)); -+ -+ if (FAILED(IMFByteStream_GetLength(source->byte_stream, &bytestream_len))) -+ return FALSE; -+ -+ switch (GST_QUERY_TYPE(query)) -+ { -+ case GST_QUERY_DURATION: -+ { -+ gst_query_parse_duration(query, &format, NULL); -+ if (format == GST_FORMAT_PERCENT) -+ { -+ gst_query_set_duration(query, GST_FORMAT_PERCENT, GST_FORMAT_PERCENT_MAX); -+ return TRUE; -+ } -+ else if (format == GST_FORMAT_BYTES) -+ { -+ QWORD length; -+ IMFByteStream_GetLength(source->byte_stream, &length); -+ gst_query_set_duration(query, GST_FORMAT_BYTES, length); -+ return TRUE; -+ } -+ return FALSE; -+ } -+ case GST_QUERY_SEEKING: -+ { -+ gst_query_parse_seeking (query, &format, NULL, NULL, NULL); -+ if (format != GST_FORMAT_BYTES) -+ { -+ WARN("Cannot seek using format \"%s\".\n", gst_format_get_name(format)); -+ return FALSE; -+ } -+ gst_query_set_seeking(query, GST_FORMAT_BYTES, 1, 0, bytestream_len); -+ return TRUE; -+ } -+ case GST_QUERY_SCHEDULING: -+ { -+ gst_query_set_scheduling(query, GST_SCHEDULING_FLAG_SEEKABLE, 1, -1, 0); -+ gst_query_add_scheduling_mode(query, GST_PAD_MODE_PULL); -+ return TRUE; -+ } -+ default: -+ { -+ WARN("Unhandled query type %s\n", GST_QUERY_TYPE_NAME(query)); -+ return FALSE; -+ } -+ } -+} -+ -+static gboolean bytestream_pad_mode_activate(GstPad *pad, GstObject *parent, GstPadMode mode, gboolean activate) -+{ -+ struct media_source *source = gst_pad_get_element_private(pad); -+ -+ TRACE("%s source pad for mediasource %p in %s mode.\n", -+ activate ? "Activating" : "Deactivating", source, gst_pad_mode_get_name(mode)); -+ -+ return mode == GST_PAD_MODE_PULL; -+} -+ -+static gboolean bytestream_pad_event_process(GstPad *pad, GstObject *parent, GstEvent *event) -+{ -+ struct media_source *source = gst_pad_get_element_private(pad); -+ -+ TRACE("source %p, type \"%s\".\n", source, GST_EVENT_TYPE_NAME(event)); -+ -+ switch (event->type) { -+ /* the seek event should fail in pull mode */ -+ case GST_EVENT_SEEK: -+ return FALSE; -+ default: -+ WARN("Ignoring \"%s\" event.\n", GST_EVENT_TYPE_NAME(event)); -+ case GST_EVENT_TAG: -+ case GST_EVENT_QOS: -+ case GST_EVENT_RECONFIGURE: -+ return gst_pad_event_default(pad, parent, event); -+ } -+ return TRUE; -+} -+ - static HRESULT WINAPI media_source_QueryInterface(IMFMediaSource *iface, REFIID riid, void **out) - { - struct media_source *source = impl_from_IMFMediaSource(iface); -@@ -211,8 +341,12 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface) - - source->state = SOURCE_SHUTDOWN; - -+ if (source->my_src) -+ gst_object_unref(GST_OBJECT(source->my_src)); - if (source->event_queue) - IMFMediaEventQueue_Shutdown(source->event_queue); -+ if (source->byte_stream) -+ IMFByteStream_Release(source->byte_stream); - - return S_OK; - } -@@ -236,19 +370,31 @@ static const IMFMediaSourceVtbl IMFMediaSource_vtbl = - - static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_source **out_media_source) - { -+ GstStaticPadTemplate src_template = -+ 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)); - HRESULT hr; - - if (!object) - return E_OUTOFMEMORY; - -+ object->IMFMediaSource_iface.lpVtbl = &IMFMediaSource_vtbl; -+ object->ref = 1; -+ object->byte_stream = bytestream; -+ IMFByteStream_AddRef(bytestream); -+ - if (FAILED(hr = MFCreateEventQueue(&object->event_queue))) - goto fail; - -- object->state = SOURCE_STOPPED; -+ object->my_src = gst_pad_new_from_static_template(&src_template, "mf-src"); -+ gst_pad_set_element_private(object->my_src, object); -+ gst_pad_set_getrange_function(object->my_src, bytestream_wrapper_pull_wrapper); -+ gst_pad_set_query_function(object->my_src, bytestream_query_wrapper); -+ gst_pad_set_activatemode_function(object->my_src, bytestream_pad_mode_activate_wrapper); -+ gst_pad_set_event_function(object->my_src, bytestream_pad_event_process_wrapper); - -- object->IMFMediaSource_iface.lpVtbl = &IMFMediaSource_vtbl; -- object->ref = 1; -+ object->state = SOURCE_STOPPED; - - *out_media_source = object; - return S_OK; -@@ -716,3 +862,40 @@ HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) - - return hr; - } -+ -+/* helper for callback forwarding */ -+void perform_cb_media_source(struct cb_data *cbdata) -+{ -+ switch(cbdata->type) -+ { -+ case BYTESTREAM_WRAPPER_PULL: -+ { -+ struct getrange_data *data = &cbdata->u.getrange_data; -+ cbdata->u.getrange_data.ret = bytestream_wrapper_pull(data->pad, data->parent, -+ data->ofs, data->len, data->buf); -+ break; -+ } -+ case BYTESTREAM_QUERY: -+ { -+ struct query_function_data *data = &cbdata->u.query_function_data; -+ cbdata->u.query_function_data.ret = bytestream_query(data->pad, data->parent, data->query); -+ break; -+ } -+ case BYTESTREAM_PAD_MODE_ACTIVATE: -+ { -+ struct activate_mode_data *data = &cbdata->u.activate_mode_data; -+ cbdata->u.activate_mode_data.ret = bytestream_pad_mode_activate(data->pad, data->parent, data->mode, data->activate); -+ break; -+ } -+ case BYTESTREAM_PAD_EVENT_PROCESS: -+ { -+ struct event_src_data *data = &cbdata->u.event_src_data; -+ cbdata->u.event_src_data.ret = bytestream_pad_event_process(data->pad, data->parent, data->event); -+ break; -+ } -+ default: -+ { -+ assert(0); -+ } -+ } -+} --- -2.28.0 - diff --git a/patches/mfplat-streaming-support/0002-winegstreamer-Use-decodebin-to-initialize-media-stre.patch b/patches/mfplat-streaming-support/0002-winegstreamer-Use-decodebin-to-initialize-media-stre.patch deleted file mode 100644 index 46866765..00000000 --- a/patches/mfplat-streaming-support/0002-winegstreamer-Use-decodebin-to-initialize-media-stre.patch +++ /dev/null @@ -1,597 +0,0 @@ -From 49b2e0568ffe3e5e2ea7e9c3572ec09ef2cf8ad7 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Tue, 31 Mar 2020 13:34:57 -0500 -Subject: [PATCH] winegstreamer: Use decodebin to initialize media streams. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/gst_cbs.c | 45 ++++ - dlls/winegstreamer/gst_cbs.h | 8 + - dlls/winegstreamer/media_source.c | 405 +++++++++++++++++++++++++++++- - 3 files changed, 457 insertions(+), 1 deletion(-) - -diff --git a/dlls/winegstreamer/gst_cbs.c b/dlls/winegstreamer/gst_cbs.c -index 12b53bc5d68..51aaefa911d 100644 ---- a/dlls/winegstreamer/gst_cbs.c -+++ b/dlls/winegstreamer/gst_cbs.c -@@ -359,3 +359,48 @@ gboolean bytestream_pad_event_process_wrapper(GstPad *pad, GstObject *parent, Gs - - return cbdata.u.event_src_data.ret; - } -+ -+GstBusSyncReply mf_src_bus_watch_wrapper(GstBus *bus, GstMessage *message, gpointer user) -+{ -+ struct cb_data cbdata = { MF_SRC_BUS_WATCH }; -+ -+ cbdata.u.watch_bus_data.bus = bus; -+ cbdata.u.watch_bus_data.msg = message; -+ cbdata.u.watch_bus_data.user = user; -+ -+ call_cb(&cbdata); -+ -+ return cbdata.u.watch_bus_data.ret; -+} -+ -+void mf_src_stream_added_wrapper(GstElement *bin, GstPad *pad, gpointer user) -+{ -+ struct cb_data cbdata = { MF_SRC_STREAM_ADDED }; -+ -+ cbdata.u.pad_added_data.element = bin; -+ cbdata.u.pad_added_data.pad = pad; -+ cbdata.u.pad_added_data.user = user; -+ -+ call_cb(&cbdata); -+} -+ -+void mf_src_stream_removed_wrapper(GstElement *element, GstPad *pad, gpointer user) -+{ -+ struct cb_data cbdata = { MF_SRC_STREAM_REMOVED }; -+ -+ cbdata.u.pad_removed_data.element = element; -+ cbdata.u.pad_removed_data.pad = pad; -+ cbdata.u.pad_removed_data.user = user; -+ -+ call_cb(&cbdata); -+} -+ -+void mf_src_no_more_pads_wrapper(GstElement *element, gpointer user) -+{ -+ struct cb_data cbdata = { MF_SRC_NO_MORE_PADS }; -+ -+ cbdata.u.no_more_pads_data.element = element; -+ cbdata.u.no_more_pads_data.user = user; -+ -+ call_cb(&cbdata); -+} -diff --git a/dlls/winegstreamer/gst_cbs.h b/dlls/winegstreamer/gst_cbs.h -index 3459a9ef8ee..a48999bbf71 100644 ---- a/dlls/winegstreamer/gst_cbs.h -+++ b/dlls/winegstreamer/gst_cbs.h -@@ -48,6 +48,10 @@ enum CB_TYPE { - BYTESTREAM_QUERY, - BYTESTREAM_PAD_MODE_ACTIVATE, - BYTESTREAM_PAD_EVENT_PROCESS, -+ MF_SRC_BUS_WATCH, -+ MF_SRC_STREAM_ADDED, -+ MF_SRC_STREAM_REMOVED, -+ MF_SRC_NO_MORE_PADS, - MEDIA_SOURCE_MAX, - }; - -@@ -164,5 +168,9 @@ GstFlowReturn bytestream_wrapper_pull_wrapper(GstPad *pad, GstObject *parent, gu - gboolean bytestream_query_wrapper(GstPad *pad, GstObject *parent, GstQuery *query) DECLSPEC_HIDDEN; - gboolean bytestream_pad_mode_activate_wrapper(GstPad *pad, GstObject *parent, GstPadMode mode, gboolean activate) DECLSPEC_HIDDEN; - gboolean bytestream_pad_event_process_wrapper(GstPad *pad, GstObject *parent, GstEvent *event) DECLSPEC_HIDDEN; -+GstBusSyncReply mf_src_bus_watch_wrapper(GstBus *bus, GstMessage *message, gpointer user) DECLSPEC_HIDDEN; -+void mf_src_stream_added_wrapper(GstElement *bin, GstPad *pad, gpointer user) DECLSPEC_HIDDEN; -+void mf_src_stream_removed_wrapper(GstElement *element, GstPad *pad, gpointer user) DECLSPEC_HIDDEN; -+void mf_src_no_more_pads_wrapper(GstElement *element, gpointer user) DECLSPEC_HIDDEN; - - #endif -diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index 1accf55c6a2..f61f84359d5 100644 ---- a/dlls/winegstreamer/media_source.c -+++ b/dlls/winegstreamer/media_source.c -@@ -24,6 +24,7 @@ - #include "gst_private.h" - #include "gst_cbs.h" - -+#include - #include - #include - -@@ -41,21 +42,47 @@ - - WINE_DEFAULT_DEBUG_CHANNEL(mfplat); - -+struct media_stream -+{ -+ IMFMediaStream IMFMediaStream_iface; -+ LONG ref; -+ struct media_source *parent_source; -+ IMFMediaEventQueue *event_queue; -+ GstElement *appsink; -+ GstPad *their_src, *my_sink; -+ enum -+ { -+ STREAM_STUB, -+ STREAM_SHUTDOWN, -+ } state; -+}; -+ - struct media_source - { - IMFMediaSource IMFMediaSource_iface; - LONG ref; - IMFMediaEventQueue *event_queue; - IMFByteStream *byte_stream; -- GstPad *my_src; -+ struct media_stream **streams; -+ ULONG stream_count; -+ GstBus *bus; -+ GstElement *container; -+ GstElement *decodebin; -+ GstPad *my_src, *their_sink; - enum - { - SOURCE_OPENING, - SOURCE_STOPPED, - SOURCE_SHUTDOWN, - } state; -+ HANDLE all_streams_event; - }; - -+static inline struct media_stream *impl_from_IMFMediaStream(IMFMediaStream *iface) -+{ -+ return CONTAINING_RECORD(iface, struct media_stream, IMFMediaStream_iface); -+} -+ - static inline struct media_source *impl_from_IMFMediaSource(IMFMediaSource *iface) - { - return CONTAINING_RECORD(iface, struct media_source, IMFMediaSource_iface); -@@ -182,6 +209,242 @@ static gboolean bytestream_pad_event_process(GstPad *pad, GstObject *parent, Gst - return TRUE; - } - -+GstBusSyncReply bus_watch(GstBus *bus, GstMessage *message, gpointer user) -+{ -+ struct media_source *source = user; -+ gchar *dbg_info = NULL; -+ GError *err = NULL; -+ -+ TRACE("source %p message type %s\n", source, GST_MESSAGE_TYPE_NAME(message)); -+ -+ switch (message->type) -+ { -+ case GST_MESSAGE_ERROR: -+ gst_message_parse_error(message, &err, &dbg_info); -+ ERR("%s: %s\n", GST_OBJECT_NAME(message->src), err->message); -+ ERR("%s\n", dbg_info); -+ g_error_free(err); -+ g_free(dbg_info); -+ break; -+ case GST_MESSAGE_WARNING: -+ gst_message_parse_warning(message, &err, &dbg_info); -+ WARN("%s: %s\n", GST_OBJECT_NAME(message->src), err->message); -+ WARN("%s\n", dbg_info); -+ g_error_free(err); -+ g_free(dbg_info); -+ break; -+ default: -+ break; -+ } -+ -+ gst_message_unref(message); -+ return GST_BUS_DROP; -+} -+ -+static HRESULT WINAPI media_stream_QueryInterface(IMFMediaStream *iface, REFIID riid, void **out) -+{ -+ struct media_stream *stream = impl_from_IMFMediaStream(iface); -+ -+ TRACE("(%p)->(%s %p)\n", stream, debugstr_guid(riid), out); -+ -+ if (IsEqualIID(riid, &IID_IMFMediaStream) || -+ IsEqualIID(riid, &IID_IMFMediaEventGenerator) || -+ IsEqualIID(riid, &IID_IUnknown)) -+ { -+ *out = &stream->IMFMediaStream_iface; -+ } -+ else -+ { -+ FIXME("(%s, %p)\n", debugstr_guid(riid), out); -+ *out = NULL; -+ return E_NOINTERFACE; -+ } -+ -+ IUnknown_AddRef((IUnknown*)*out); -+ return S_OK; -+} -+ -+static ULONG WINAPI media_stream_AddRef(IMFMediaStream *iface) -+{ -+ struct media_stream *stream = impl_from_IMFMediaStream(iface); -+ ULONG ref = InterlockedIncrement(&stream->ref); -+ -+ TRACE("(%p) ref=%u\n", stream, ref); -+ -+ return ref; -+} -+ -+static ULONG WINAPI media_stream_Release(IMFMediaStream *iface) -+{ -+ struct media_stream *stream = impl_from_IMFMediaStream(iface); -+ -+ ULONG ref = InterlockedDecrement(&stream->ref); -+ -+ TRACE("(%p) ref=%u\n", stream, ref); -+ -+ if (!ref) -+ { -+ if (stream->my_sink) -+ gst_object_unref(GST_OBJECT(stream->my_sink)); -+ if (stream->event_queue) -+ IMFMediaEventQueue_Release(stream->event_queue); -+ if (stream->parent_source) -+ IMFMediaSource_Release(&stream->parent_source->IMFMediaSource_iface); -+ -+ heap_free(stream); -+ } -+ -+ return ref; -+} -+ -+static HRESULT WINAPI media_stream_GetEvent(IMFMediaStream *iface, DWORD flags, IMFMediaEvent **event) -+{ -+ struct media_stream *stream = impl_from_IMFMediaStream(iface); -+ -+ TRACE("(%p)->(%#x, %p)\n", stream, flags, event); -+ -+ if (stream->state == STREAM_SHUTDOWN) -+ return MF_E_SHUTDOWN; -+ -+ return IMFMediaEventQueue_GetEvent(stream->event_queue, flags, event); -+} -+ -+static HRESULT WINAPI media_stream_BeginGetEvent(IMFMediaStream *iface, IMFAsyncCallback *callback, IUnknown *state) -+{ -+ struct media_stream *stream = impl_from_IMFMediaStream(iface); -+ -+ TRACE("(%p)->(%p, %p)\n", stream, callback, state); -+ -+ if (stream->state == STREAM_SHUTDOWN) -+ return MF_E_SHUTDOWN; -+ -+ return IMFMediaEventQueue_BeginGetEvent(stream->event_queue, callback, state); -+} -+ -+static HRESULT WINAPI media_stream_EndGetEvent(IMFMediaStream *iface, IMFAsyncResult *result, IMFMediaEvent **event) -+{ -+ struct media_stream *stream = impl_from_IMFMediaStream(iface); -+ -+ TRACE("(%p)->(%p, %p)\n", stream, result, event); -+ -+ if (stream->state == STREAM_SHUTDOWN) -+ return MF_E_SHUTDOWN; -+ -+ return IMFMediaEventQueue_EndGetEvent(stream->event_queue, result, event); -+} -+ -+static HRESULT WINAPI media_stream_QueueEvent(IMFMediaStream *iface, MediaEventType event_type, REFGUID ext_type, -+ HRESULT hr, const PROPVARIANT *value) -+{ -+ struct media_stream *stream = impl_from_IMFMediaStream(iface); -+ -+ TRACE("(%p)->(%d, %s, %#x, %p)\n", stream, event_type, debugstr_guid(ext_type), hr, value); -+ -+ if (stream->state == STREAM_SHUTDOWN) -+ return MF_E_SHUTDOWN; -+ -+ return IMFMediaEventQueue_QueueEventParamVar(stream->event_queue, event_type, ext_type, hr, value); -+} -+ -+static HRESULT WINAPI media_stream_GetMediaSource(IMFMediaStream *iface, IMFMediaSource **source) -+{ -+ struct media_stream *stream = impl_from_IMFMediaStream(iface); -+ -+ FIXME("stub (%p)->(%p)\n", stream, source); -+ -+ if (stream->state == STREAM_SHUTDOWN) -+ return MF_E_SHUTDOWN; -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI media_stream_GetStreamDescriptor(IMFMediaStream* iface, IMFStreamDescriptor **descriptor) -+{ -+ struct media_stream *stream = impl_from_IMFMediaStream(iface); -+ -+ TRACE("(%p)->(%p)\n", stream, descriptor); -+ -+ if (stream->state == STREAM_SHUTDOWN) -+ return MF_E_SHUTDOWN; -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI media_stream_RequestSample(IMFMediaStream *iface, IUnknown *token) -+{ -+ struct media_stream *stream = impl_from_IMFMediaStream(iface); -+ -+ TRACE("(%p)->(%p)\n", iface, token); -+ -+ if (stream->state == STREAM_SHUTDOWN) -+ return MF_E_SHUTDOWN; -+ -+ return E_NOTIMPL; -+} -+ -+static const IMFMediaStreamVtbl media_stream_vtbl = -+{ -+ media_stream_QueryInterface, -+ media_stream_AddRef, -+ media_stream_Release, -+ media_stream_GetEvent, -+ media_stream_BeginGetEvent, -+ media_stream_EndGetEvent, -+ media_stream_QueueEvent, -+ media_stream_GetMediaSource, -+ media_stream_GetStreamDescriptor, -+ media_stream_RequestSample -+}; -+ -+/* creates a stub stream */ -+static HRESULT new_media_stream(struct media_source *source, GstPad *pad, struct media_stream **out_stream) -+{ -+ struct media_stream *object = heap_alloc_zero(sizeof(*object)); -+ HRESULT hr; -+ -+ TRACE("(%p %p)->(%p)\n", source, pad, out_stream); -+ -+ object->IMFMediaStream_iface.lpVtbl = &media_stream_vtbl; -+ object->ref = 1; -+ -+ IMFMediaSource_AddRef(&source->IMFMediaSource_iface); -+ object->parent_source = source; -+ object->their_src = pad; -+ -+ object->state = STREAM_STUB; -+ -+ if (FAILED(hr = MFCreateEventQueue(&object->event_queue))) -+ goto fail; -+ -+ if (!(object->appsink = gst_element_factory_make("appsink", NULL))) -+ { -+ hr = E_OUTOFMEMORY; -+ goto fail; -+ } -+ gst_bin_add(GST_BIN(object->parent_source->container), object->appsink); -+ -+ 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_set_element_private(object->my_sink, object); -+ -+ gst_pad_link(object->their_src, object->my_sink); -+ -+ gst_element_sync_state_with_parent(object->appsink); -+ -+ TRACE("->(%p)\n", object); -+ *out_stream = object; -+ -+ return S_OK; -+ -+fail: -+ WARN("Failed to construct media stream, hr %#x.\n", hr); -+ -+ IMFMediaStream_Release(&object->IMFMediaStream_iface); -+ return hr; -+} -+ - static HRESULT WINAPI media_source_QueryInterface(IMFMediaSource *iface, REFIID riid, void **out) - { - struct media_source *source = impl_from_IMFMediaSource(iface); -@@ -333,6 +596,7 @@ static HRESULT WINAPI media_source_Pause(IMFMediaSource *iface) - static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface) - { - struct media_source *source = impl_from_IMFMediaSource(iface); -+ unsigned int i; - - TRACE("(%p)\n", source); - -@@ -341,13 +605,34 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface) - - source->state = SOURCE_SHUTDOWN; - -+ if (source->container) -+ { -+ gst_element_set_state(source->container, GST_STATE_NULL); -+ gst_object_unref(GST_OBJECT(source->container)); -+ } -+ - if (source->my_src) - gst_object_unref(GST_OBJECT(source->my_src)); -+ if (source->their_sink) -+ gst_object_unref(GST_OBJECT(source->their_sink)); -+ - if (source->event_queue) - IMFMediaEventQueue_Shutdown(source->event_queue); - if (source->byte_stream) - IMFByteStream_Release(source->byte_stream); - -+ for (i = 0; i < source->stream_count; i++) -+ { -+ source->streams[i]->state = STREAM_SHUTDOWN; -+ IMFMediaStream_Release(&source->streams[i]->IMFMediaStream_iface); -+ } -+ -+ if (source->stream_count) -+ heap_free(source->streams); -+ -+ if (source->all_streams_event) -+ CloseHandle(source->all_streams_event); -+ - return S_OK; - } - -@@ -368,6 +653,50 @@ static const IMFMediaSourceVtbl IMFMediaSource_vtbl = - media_source_Shutdown, - }; - -+static void stream_added(GstElement *element, GstPad *pad, gpointer user) -+{ -+ struct media_source *source = user; -+ struct media_stream **new_stream_array; -+ struct media_stream *stream; -+ -+ if (gst_pad_get_direction(pad) != GST_PAD_SRC) -+ return; -+ -+ if (FAILED(new_media_stream(source, pad, &stream))) -+ return; -+ -+ if (!(new_stream_array = heap_realloc(source->streams, (source->stream_count + 1) * (sizeof(*new_stream_array))))) -+ { -+ ERR("Failed to add stream to source\n"); -+ IMFMediaStream_Release(&stream->IMFMediaStream_iface); -+ return; -+ } -+ -+ source->streams = new_stream_array; -+ source->streams[source->stream_count++] = stream; -+} -+ -+static void stream_removed(GstElement *element, GstPad *pad, gpointer user) -+{ -+ struct media_source *source = user; -+ unsigned int i; -+ -+ for (i = 0; i < source->stream_count; i++) -+ { -+ struct media_stream *stream = source->streams[i]; -+ if (stream->their_src != pad) -+ continue; -+ stream->their_src = NULL; -+ } -+} -+ -+static void no_more_pads(GstElement *element, gpointer user) -+{ -+ struct media_source *source = user; -+ -+ SetEvent(source->all_streams_event); -+} -+ - static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_source **out_media_source) - { - GstStaticPadTemplate src_template = -@@ -375,6 +704,7 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ - - struct media_source *object = heap_alloc_zero(sizeof(*object)); - HRESULT hr; -+ int ret; - - if (!object) - return E_OUTOFMEMORY; -@@ -383,10 +713,16 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ - object->ref = 1; - object->byte_stream = bytestream; - IMFByteStream_AddRef(bytestream); -+ object->all_streams_event = CreateEventA(NULL, FALSE, FALSE, NULL); - - if (FAILED(hr = MFCreateEventQueue(&object->event_queue))) - goto fail; - -+ 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); -+ gst_element_set_bus(object->container, object->bus); -+ - object->my_src = gst_pad_new_from_static_template(&src_template, "mf-src"); - gst_pad_set_element_private(object->my_src, object); - gst_pad_set_getrange_function(object->my_src, bytestream_wrapper_pull_wrapper); -@@ -394,6 +730,49 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ - gst_pad_set_activatemode_function(object->my_src, bytestream_pad_mode_activate_wrapper); - gst_pad_set_event_function(object->my_src, bytestream_pad_event_process_wrapper); - -+ if (!(object->decodebin = gst_element_factory_make("decodebin", NULL))) -+ { -+ WARN("Failed to create decodebin for source\n"); -+ hr = E_OUTOFMEMORY; -+ goto fail; -+ } -+ -+ /* In Media Foundation, sources will infinitely leak buffers, when a subset of the selected -+ streams are read from. This behavior is relied upon in the Unity3D engine game, Trailmakers, -+ where Unity selects both the video and audio streams, yet only reads from the video stream. -+ Removing these buffering limits reflects that behavior. */ -+ g_object_set(object->decodebin, "max-size-buffers", 0, NULL); -+ g_object_set(object->decodebin, "max-size-time", G_GUINT64_CONSTANT(0), NULL); -+ g_object_set(object->decodebin, "max-size-bytes", 0, NULL); -+ -+ gst_bin_add(GST_BIN(object->container), object->decodebin); -+ -+ g_signal_connect(object->decodebin, "pad-added", G_CALLBACK(mf_src_stream_added_wrapper), object); -+ 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); -+ -+ object->their_sink = gst_element_get_static_pad(object->decodebin, "sink"); -+ -+ if ((ret = gst_pad_link(object->my_src, object->their_sink)) < 0) -+ { -+ WARN("Failed to link our bytestream pad to the demuxer input\n"); -+ hr = E_OUTOFMEMORY; -+ goto fail; -+ } -+ -+ object->state = SOURCE_OPENING; -+ -+ gst_element_set_state(object->container, GST_STATE_PAUSED); -+ ret = gst_element_get_state(object->container, NULL, NULL, -1); -+ if (ret == GST_STATE_CHANGE_FAILURE) -+ { -+ ERR("Failed to play source.\n"); -+ hr = E_OUTOFMEMORY; -+ goto fail; -+ } -+ -+ WaitForSingleObject(object->all_streams_event, INFINITE); -+ - object->state = SOURCE_STOPPED; - - *out_media_source = object; -@@ -893,6 +1272,30 @@ void perform_cb_media_source(struct cb_data *cbdata) - cbdata->u.event_src_data.ret = bytestream_pad_event_process(data->pad, data->parent, data->event); - break; - } -+ case MF_SRC_BUS_WATCH: -+ { -+ struct watch_bus_data *data = &cbdata->u.watch_bus_data; -+ cbdata->u.watch_bus_data.ret = bus_watch(data->bus, data->msg, data->user); -+ break; -+ } -+ case MF_SRC_STREAM_ADDED: -+ { -+ struct pad_added_data *data = &cbdata->u.pad_added_data; -+ stream_added(data->element, data->pad, data->user); -+ break; -+ } -+ case MF_SRC_STREAM_REMOVED: -+ { -+ struct pad_removed_data *data = &cbdata->u.pad_removed_data; -+ stream_removed(data->element, data->pad, data->user); -+ break; -+ } -+ case MF_SRC_NO_MORE_PADS: -+ { -+ struct no_more_pads_data *data = &cbdata->u.no_more_pads_data; -+ no_more_pads(data->element, data->user); -+ break; -+ } - default: - { - assert(0); --- -2.28.0 - diff --git a/patches/mfplat-streaming-support/0003-winegstreamer-Implement-IMFMediaStream-GetStreamDesc.patch b/patches/mfplat-streaming-support/0003-winegstreamer-Implement-IMFMediaStream-GetStreamDesc.patch deleted file mode 100644 index 9c9d97d3..00000000 --- a/patches/mfplat-streaming-support/0003-winegstreamer-Implement-IMFMediaStream-GetStreamDesc.patch +++ /dev/null @@ -1,381 +0,0 @@ -From 5119cb0704635fb1b4e30f4b67f86826b28e6015 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Fri, 11 Sep 2020 13:51:20 -0500 -Subject: [PATCH] winegstreamer: Implement IMFMediaStream::GetStreamDescriptor. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/gst_private.h | 4 + - dlls/winegstreamer/media_source.c | 75 +++++++++++++- - dlls/winegstreamer/mfplat.c | 166 ++++++++++++++++++++++++++++++ - 3 files changed, 240 insertions(+), 5 deletions(-) - -diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h -index ef07d3591e7..60b38a48f5a 100644 ---- a/dlls/winegstreamer/gst_private.h -+++ b/dlls/winegstreamer/gst_private.h -@@ -36,6 +36,7 @@ - #include "winuser.h" - #include "dshow.h" - #include "strmif.h" -+#include "mfobjects.h" - #include "wine/heap.h" - #include "wine/strmbase.h" - -@@ -54,6 +55,9 @@ 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; -+IMFMediaType *mf_media_type_from_caps(const GstCaps *caps) DECLSPEC_HIDDEN; -+ - HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN; - - #endif /* __GST_PRIVATE_INCLUDED__ */ -diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index f61f84359d5..723f052c10d 100644 ---- a/dlls/winegstreamer/media_source.c -+++ b/dlls/winegstreamer/media_source.c -@@ -48,13 +48,17 @@ struct media_stream - LONG ref; - struct media_source *parent_source; - IMFMediaEventQueue *event_queue; -+ IMFStreamDescriptor *descriptor; - GstElement *appsink; - GstPad *their_src, *my_sink; - enum - { - STREAM_STUB, -+ STREAM_INACTIVE, - STREAM_SHUTDOWN, - } state; -+ /* used when in STUB state: */ -+ DWORD stream_id; - }; - - struct media_source -@@ -286,6 +290,8 @@ static ULONG WINAPI media_stream_Release(IMFMediaStream *iface) - { - if (stream->my_sink) - gst_object_unref(GST_OBJECT(stream->my_sink)); -+ if (stream->descriptor) -+ IMFStreamDescriptor_Release(stream->descriptor); - if (stream->event_queue) - IMFMediaEventQueue_Release(stream->event_queue); - if (stream->parent_source) -@@ -367,7 +373,10 @@ static HRESULT WINAPI media_stream_GetStreamDescriptor(IMFMediaStream* iface, IM - if (stream->state == STREAM_SHUTDOWN) - return MF_E_SHUTDOWN; - -- return E_NOTIMPL; -+ IMFStreamDescriptor_AddRef(stream->descriptor); -+ *descriptor = stream->descriptor; -+ -+ return S_OK; - } - - static HRESULT WINAPI media_stream_RequestSample(IMFMediaStream *iface, IUnknown *token) -@@ -397,7 +406,7 @@ static const IMFMediaStreamVtbl media_stream_vtbl = - }; - - /* creates a stub stream */ --static HRESULT new_media_stream(struct media_source *source, GstPad *pad, struct media_stream **out_stream) -+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)); - HRESULT hr; -@@ -410,6 +419,7 @@ static HRESULT new_media_stream(struct media_source *source, GstPad *pad, struct - IMFMediaSource_AddRef(&source->IMFMediaSource_iface); - object->parent_source = source; - object->their_src = pad; -+ object->stream_id = stream_id; - - object->state = STREAM_STUB; - -@@ -427,8 +437,6 @@ static HRESULT new_media_stream(struct media_source *source, GstPad *pad, struct - g_object_set(object->appsink, "max-buffers", 5, NULL); - - object->my_sink = gst_element_get_static_pad(object->appsink, "sink"); -- gst_pad_set_element_private(object->my_sink, object); -- - gst_pad_link(object->their_src, object->my_sink); - - gst_element_sync_state_with_parent(object->appsink); -@@ -445,6 +453,47 @@ fail: - return hr; - } - -+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_type = NULL; -+ HRESULT hr; -+ -+ if (!current_caps) -+ { -+ hr = E_FAIL; -+ goto fail; -+ } -+ -+ stream_type = mf_media_type_from_caps(current_caps); -+ gst_caps_unref(current_caps); -+ if (!stream_type) -+ { -+ hr = E_FAIL; -+ goto fail; -+ } -+ -+ if (FAILED(hr = MFCreateStreamDescriptor(stream->stream_id, 1, &stream_type, &stream->descriptor))) -+ goto fail; -+ -+ if (FAILED(hr = IMFStreamDescriptor_GetMediaTypeHandler(stream->descriptor, &type_handler))) -+ goto fail; -+ -+ if (FAILED(hr = IMFMediaTypeHandler_SetCurrentMediaType(type_handler, stream_type))) -+ goto fail; -+ -+ IMFMediaTypeHandler_Release(type_handler); -+ -+ stream->state = STREAM_INACTIVE; -+ -+ return S_OK; -+ fail: -+ if (type_handler) -+ IMFMediaTypeHandler_Release(type_handler); -+ return hr; -+} -+ - static HRESULT WINAPI media_source_QueryInterface(IMFMediaSource *iface, REFIID riid, void **out) - { - struct media_source *source = impl_from_IMFMediaSource(iface); -@@ -662,7 +711,7 @@ static void stream_added(GstElement *element, GstPad *pad, gpointer user) - if (gst_pad_get_direction(pad) != GST_PAD_SRC) - return; - -- if (FAILED(new_media_stream(source, pad, &stream))) -+ if (FAILED(new_media_stream(source, pad, source->stream_count, &stream))) - return; - - if (!(new_stream_array = heap_realloc(source->streams, (source->stream_count + 1) * (sizeof(*new_stream_array))))) -@@ -687,6 +736,8 @@ static void stream_removed(GstElement *element, GstPad *pad, gpointer user) - if (stream->their_src != pad) - continue; - stream->their_src = NULL; -+ if (stream->state != STREAM_INACTIVE) -+ stream->state = STREAM_INACTIVE; - } - } - -@@ -703,6 +754,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)); -+ unsigned int i; - HRESULT hr; - int ret; - -@@ -772,6 +824,19 @@ static HRESULT media_source_constructor(IMFByteStream *bytestream, struct media_ - } - - WaitForSingleObject(object->all_streams_event, INFINITE); -+ for (i = 0; i < object->stream_count; i++) -+ { -+ GstSample *preroll; -+ g_signal_emit_by_name(object->streams[i]->appsink, "pull-preroll", &preroll); -+ hr = E_FAIL; -+ if (!preroll || FAILED(hr = media_stream_init_desc(object->streams[i]))) -+ { -+ ERR("Failed to finish initialization of media stream %p, hr %x.\n", object->streams[i], hr); -+ IMFMediaStream_Release(&object->streams[i]->IMFMediaStream_iface); -+ goto fail; -+ } -+ gst_sample_unref(preroll); -+ } - - object->state = SOURCE_STOPPED; - -diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index c996f06211e..2c2216f94b6 100644 ---- a/dlls/winegstreamer/mfplat.c -+++ b/dlls/winegstreamer/mfplat.c -@@ -16,6 +16,11 @@ - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -+#include "config.h" -+#include -+ -+#include "gst_private.h" -+ - #include - - #include "gst_private.h" -@@ -436,3 +441,164 @@ HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) - - return CLASS_E_CLASSNOTAVAILABLE; - } -+ -+static const struct -+{ -+ const GUID *subtype; -+ GstVideoFormat format; -+} -+uncompressed_video_formats[] = -+{ -+ {&MFVideoFormat_ARGB32, GST_VIDEO_FORMAT_BGRA}, -+ {&MFVideoFormat_RGB32, GST_VIDEO_FORMAT_BGRx}, -+ {&MFVideoFormat_RGB24, GST_VIDEO_FORMAT_BGR}, -+ {&MFVideoFormat_RGB565, GST_VIDEO_FORMAT_BGR16}, -+ {&MFVideoFormat_RGB555, GST_VIDEO_FORMAT_BGR15}, -+}; -+ -+/* returns NULL if doesn't match exactly */ -+IMFMediaType *mf_media_type_from_caps(const GstCaps *caps) -+{ -+ IMFMediaType *media_type; -+ GstStructure *info; -+ const char *mime_type; -+ -+ if (TRACE_ON(mfplat)) -+ { -+ gchar *human_readable = gst_caps_to_string(caps); -+ TRACE("caps = %s\n", debugstr_a(human_readable)); -+ g_free(human_readable); -+ } -+ -+ if (FAILED(MFCreateMediaType(&media_type))) -+ return NULL; -+ -+ info = gst_caps_get_structure(caps, 0); -+ mime_type = gst_structure_get_name(info); -+ -+ if (!strncmp(mime_type, "video", 5)) -+ { -+ GstVideoInfo video_info; -+ -+ if (!gst_video_info_from_caps(&video_info, caps)) -+ { -+ return NULL; -+ } -+ -+ IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video); -+ -+ IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, ((UINT64)video_info.width << 32) | video_info.height); -+ -+ IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_RATE, ((UINT64)video_info.fps_n << 32) | video_info.fps_d); -+ -+ if (!strcmp(mime_type, "video/x-raw")) -+ { -+ GUID fourcc_subtype = MFVideoFormat_Base; -+ unsigned int i; -+ -+ IMFMediaType_SetUINT32(media_type, &MF_MT_COMPRESSED, FALSE); -+ -+ /* First try FOURCC */ -+ if ((fourcc_subtype.Data1 = gst_video_format_to_fourcc(video_info.finfo->format))) -+ { -+ IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &fourcc_subtype); -+ } -+ else -+ { -+ for (i = 0; i < ARRAY_SIZE(uncompressed_video_formats); i++) -+ { -+ if (uncompressed_video_formats[i].format == video_info.finfo->format) -+ { -+ IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, uncompressed_video_formats[i].subtype); -+ break; -+ } -+ } -+ if (i == ARRAY_SIZE(uncompressed_video_formats)) -+ { -+ FIXME("Unrecognized uncompressed video format %x\n", video_info.finfo->format); -+ IMFMediaType_Release(media_type); -+ return NULL; -+ } -+ } -+ } -+ else -+ { -+ FIXME("Unrecognized video format %s\n", mime_type); -+ return NULL; -+ } -+ } -+ else if (!strncmp(mime_type, "audio", 5)) -+ { -+ gint rate, channels, bitrate; -+ guint64 channel_mask; -+ IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); -+ -+ if (gst_structure_get_int(info, "rate", &rate)) -+ IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, rate); -+ -+ if (gst_structure_get_int(info, "channels", &channels)) -+ IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_NUM_CHANNELS, channels); -+ -+ if (gst_structure_get(info, "channel-mask", GST_TYPE_BITMASK, &channel_mask, NULL)) -+ IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_CHANNEL_MASK, channel_mask); -+ -+ if (gst_structure_get_int(info, "bitrate", &bitrate)) -+ IMFMediaType_SetUINT32(media_type, &MF_MT_AVG_BITRATE, bitrate); -+ -+ if (!strcmp(mime_type, "audio/x-raw")) -+ { -+ GstAudioInfo audio_info; -+ -+ if (gst_audio_info_from_caps(&audio_info, caps)) -+ { -+ DWORD depth = GST_AUDIO_INFO_DEPTH(&audio_info); -+ -+ /* validation */ -+ if ((audio_info.finfo->flags & GST_AUDIO_FORMAT_FLAG_INTEGER && depth > 8) || -+ (audio_info.finfo->flags & GST_AUDIO_FORMAT_FLAG_SIGNED && depth <= 8) || -+ (audio_info.finfo->endianness != G_LITTLE_ENDIAN && depth > 8)) -+ { -+ IMFMediaType_Release(media_type); -+ return NULL; -+ } -+ -+ /* conversion */ -+ switch (audio_info.finfo->flags) -+ { -+ case GST_AUDIO_FORMAT_FLAG_FLOAT: -+ IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_Float); -+ break; -+ case GST_AUDIO_FORMAT_FLAG_INTEGER: -+ case GST_AUDIO_FORMAT_FLAG_SIGNED: -+ IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); -+ break; -+ default: -+ FIXME("Unrecognized audio format %x\n", audio_info.finfo->format); -+ IMFMediaType_Release(media_type); -+ return NULL; -+ } -+ -+ IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_BITS_PER_SAMPLE, depth); -+ } -+ else -+ { -+ ERR("Failed to get caps audio info\n"); -+ IMFMediaType_Release(media_type); -+ return NULL; -+ } -+ } -+ else -+ { -+ FIXME("Unrecognized audio format %s\n", mime_type); -+ IMFMediaType_Release(media_type); -+ return NULL; -+ } -+ } -+ else -+ { -+ IMFMediaType_Release(media_type); -+ return NULL; -+ } -+ -+ return media_type; -+} --- -2.28.0 - diff --git a/patches/mfplat-streaming-support/definition b/patches/mfplat-streaming-support/definition index 46a40d0b..6fde82d1 100644 --- a/patches/mfplat-streaming-support/definition +++ b/patches/mfplat-streaming-support/definition @@ -1 +1,2 @@ Fixes: [49692] mfplat: Improved support for multiple video formats. +Disabled: true diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index ffb9da02..83886b1c 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -51,7 +51,7 @@ usage() # Get the upstream commit sha upstream_commit() { - echo "2ee75bf9ade3e90f10ffe4236c8c95d817402392" + echo "23c6dd55b8c983ec88cada0a6d6c75ee9cd93976" } # Show version information @@ -88,7 +88,6 @@ patch_enable_all () enable_advapi32_LsaLookupPrivilegeName="$1" enable_api_ms_win_Stub_DLLs="$1" enable_atl_AtlAxDialogBox="$1" - enable_bcrypt_ECDHSecretAgreement="$1" enable_cmd_launch_association="$1" enable_color_sRGB_profile="$1" enable_comctl32_Listview_DrawItem="$1" @@ -107,7 +106,6 @@ patch_enable_all () enable_d3dx9_36_D3DXStubs="$1" enable_d3dx9_36_DDS="$1" enable_d3dx9_36_Filter_Warnings="$1" - enable_d3dx9_36_Optimize_Inplace="$1" enable_d3dx9_36_UpdateSkinnedMesh="$1" enable_dbghelp_Debug_Symbols="$1" enable_ddraw_Device_Caps="$1" @@ -146,7 +144,6 @@ patch_enable_all () enable_krnl386_exe16_GDT_LDT_Emulation="$1" enable_krnl386_exe16_Invalid_Console_Handles="$1" enable_loader_KeyboardLayouts="$1" - enable_mfplat_streaming_support="$1" enable_mmsystem_dll16_MIDIHDR_Refcount="$1" enable_mountmgr_DosDevices="$1" enable_mscoree_CorValidateImage="$1" @@ -358,9 +355,6 @@ patch_enable () atl-AtlAxDialogBox) enable_atl_AtlAxDialogBox="$2" ;; - bcrypt-ECDHSecretAgreement) - enable_bcrypt_ECDHSecretAgreement="$2" - ;; cmd-launch-association) enable_cmd_launch_association="$2" ;; @@ -415,9 +409,6 @@ patch_enable () d3dx9_36-Filter_Warnings) enable_d3dx9_36_Filter_Warnings="$2" ;; - d3dx9_36-Optimize_Inplace) - enable_d3dx9_36_Optimize_Inplace="$2" - ;; d3dx9_36-UpdateSkinnedMesh) enable_d3dx9_36_UpdateSkinnedMesh="$2" ;; @@ -532,9 +523,6 @@ patch_enable () loader-KeyboardLayouts) enable_loader_KeyboardLayouts="$2" ;; - mfplat-streaming-support) - enable_mfplat_streaming_support="$2" - ;; mmsystem.dll16-MIDIHDR_Refcount) enable_mmsystem_dll16_MIDIHDR_Refcount="$2" ;; @@ -1840,21 +1828,6 @@ if test "$enable_atl_AtlAxDialogBox" -eq 1; then patch_apply atl-AtlAxDialogBox/0001-atl-Implement-AtlAxDialogBox-A-W.patch fi -# Patchset bcrypt-ECDHSecretAgreement -# | -# | This patchset fixes the following Wine bugs: -# | * [#47699] Multiple games fail to connect to online services (missing BCryptSecretAgreement / BCryptDeriveKey -# | implementation) -# | -# | Modified files: -# | * configure.ac, dlls/bcrypt/Makefile.in, dlls/bcrypt/bcrypt_internal.h, dlls/bcrypt/bcrypt_main.c, dlls/bcrypt/gcrypt.c, -# | dlls/bcrypt/gnutls.c, dlls/bcrypt/macos.c, dlls/bcrypt/tests/bcrypt.c -# | -if test "$enable_bcrypt_ECDHSecretAgreement" -eq 1; then - patch_apply bcrypt-ECDHSecretAgreement/0001-bcrypt-Implement-BCryptSecretAgreement-with-libgcryp.patch - patch_apply bcrypt-ECDHSecretAgreement/0002-bcrypt-Implement-BCRYPT_KDF_HASH.patch -fi - # Patchset cmd-launch-association # | # | This patchset fixes the following Wine bugs: @@ -2196,18 +2169,6 @@ if test "$enable_d3dx9_36_Filter_Warnings" -eq 1; then patch_apply d3dx9_36-Filter_Warnings/0001-d3dx9_36-Filter-out-D3DCompile-warning-messages-that.patch fi -# Patchset d3dx9_36-Optimize_Inplace -# | -# | This patchset fixes the following Wine bugs: -# | * [#48529] Avencast fails to launch -# | -# | Modified files: -# | * dlls/d3dx9_36/mesh.c -# | -if test "$enable_d3dx9_36_Optimize_Inplace" -eq 1; then - patch_apply d3dx9_36-Optimize_Inplace/0001-d3dx9_36-No-need-to-fail-if-we-don-t-support-vertice.patch -fi - # Patchset d3dx9_36-UpdateSkinnedMesh # | # | This patchset fixes the following Wine bugs: @@ -2718,78 +2679,6 @@ if test "$enable_loader_KeyboardLayouts" -eq 1; then patch_apply loader-KeyboardLayouts/0002-user32-Improve-GetKeyboardLayoutList.patch fi -# Patchset mfplat-streaming-support -# | -# | This patchset fixes the following Wine bugs: -# | * [#49692] mfplat: Improved support for multiple video formats. -# | -# | Modified files: -# | * configure.ac, dlls/mf/Makefile.in, dlls/mf/handler.c, dlls/mf/handler.h, dlls/mf/main.c, dlls/mf/sar.c, -# | dlls/mf/session.c, dlls/mf/tests/mf.c, dlls/mf/topology.c, dlls/mfplat/mediatype.c, dlls/mfplat/tests/mfplat.c, -# | dlls/mfplat/tests/test.mp4, dlls/mfreadwrite/reader.c, dlls/mfreadwrite/tests/mfplat.c, -# | dlls/mfreadwrite/tests/resource.rc, dlls/mfreadwrite/tests/test.mp4, dlls/winegstreamer/Makefile.in, -# | dlls/winegstreamer/audioconvert.c, dlls/winegstreamer/colorconvert.c, dlls/winegstreamer/gst_cbs.c, -# | dlls/winegstreamer/gst_cbs.h, dlls/winegstreamer/gst_private.h, dlls/winegstreamer/main.c, -# | dlls/winegstreamer/media_source.c, dlls/winegstreamer/mf_decode.c, dlls/winegstreamer/mfplat.c, -# | dlls/winegstreamer/winegstreamer_classes.idl, include/mfidl.idl, tools/make_makefiles, tools/makedep.c -# | -if test "$enable_mfplat_streaming_support" -eq 1; then - patch_apply mfplat-streaming-support/0001-winegstreamer-Add-a-GstPad-wrapping-the-media-source.patch - patch_apply mfplat-streaming-support/0002-winegstreamer-Use-decodebin-to-initialize-media-stre.patch - patch_apply mfplat-streaming-support/0003-winegstreamer-Implement-IMFMediaStream-GetStreamDesc.patch - patch_apply mfplat-streaming-support/0004-winegstreamer-Insert-parser-into-pipeline-to-rectify.patch - patch_apply mfplat-streaming-support/0005-winegstreamer-Insert-videoconvert-into-decoded-video.patch - patch_apply mfplat-streaming-support/0006-winegstreamer-Insert-audioconvert-into-decoded-audio.patch - patch_apply mfplat-streaming-support/0007-winegstreamer-Translate-H.264-caps-to-attributes.patch - patch_apply mfplat-streaming-support/0008-winegstreamer-Translate-WMV-caps-to-attributes.patch - patch_apply mfplat-streaming-support/0009-winegstreamer-Translate-AAC-caps-to-attributes.patch - patch_apply mfplat-streaming-support/0010-winegstreamer-Translate-MPEG-4-Section-2-caps-to-att.patch - patch_apply mfplat-streaming-support/0011-winegstreamer-Translate-WMA-caps-to-attributes.patch - patch_apply mfplat-streaming-support/0012-winegstreamer-Implement-IMFMediaSource-CreatePresent.patch - patch_apply mfplat-streaming-support/0013-winegstreamer-Introduce-IMFMediaType-GstCaps-convert.patch - patch_apply mfplat-streaming-support/0014-winegstreamer-Translate-H.264-attributes-to-caps.patch - patch_apply mfplat-streaming-support/0015-winegstreamer-Translate-WMV-attributes-to-caps.patch - patch_apply mfplat-streaming-support/0016-winegstreamer-Translate-AAC-attributes-to-caps.patch - patch_apply mfplat-streaming-support/0017-winegstreamer-Translate-MPEG-4-Section-2-attributes-.patch - patch_apply mfplat-streaming-support/0018-winegstreamer-Translate-WMA-attributes-to-caps.patch - patch_apply mfplat-streaming-support/0019-winegstreamer-Implement-IMFMediaSource-Start.patch - patch_apply mfplat-streaming-support/0020-winegstreamer-Implement-IMFMediaStream-RequestSample.patch - patch_apply mfplat-streaming-support/0021-winegstreamer-Implement-IMFMediaSource-GetCharacteri.patch - patch_apply mfplat-streaming-support/0022-winegstreamer-Calculate-the-MF_PD_DURATION-of-the-me.patch - patch_apply mfplat-streaming-support/0023-tools-Add-support-for-multiple-parent-directories.patch - patch_apply mfplat-streaming-support/0024-mf-Introduce-handler-helper.patch - patch_apply mfplat-streaming-support/0025-Introduce-IMFSample-GstBuffer-converter.patch - patch_apply mfplat-streaming-support/0026-winegstreamer-Implement-decoder-MFT-on-gstreamer.patch - patch_apply mfplat-streaming-support/0027-mfreadwrite-Select-all-streams-when-creating-a-sourc.patch - patch_apply mfplat-streaming-support/0028-Miscellaneous.patch - patch_apply mfplat-streaming-support/0029-WMV.patch - patch_apply mfplat-streaming-support/0030-mf-Ask-for-more-samples-from-upstream-node-when-upon.patch - patch_apply mfplat-streaming-support/0031-winegstreamer-Implement-IMFMedisStream-GetMediaSourc.patch - patch_apply mfplat-streaming-support/0032-Expose-PCM-output-type-on-AAC-decoder.patch - patch_apply mfplat-streaming-support/0033-mfplat-Add-I420-format-information.patch - patch_apply mfplat-streaming-support/0034-winegstreamer-Implement-Color-Converter-MFT.patch - patch_apply mfplat-streaming-support/0035-HACK-Set-BPS-to-16-for-output-template.patch - patch_apply mfplat-streaming-support/0036-Improve-tests.patch - patch_apply mfplat-streaming-support/0037-Revert-Improve-tests.patch - patch_apply mfplat-streaming-support/0038-Report-streams-backwards-and-only-select-one-of-each.patch - patch_apply mfplat-streaming-support/0039-winegstreamer-Implement-IMFMediaSource-Stop.patch - patch_apply mfplat-streaming-support/0040-winegstreamer-Introduce-MPEG-4-Section-2-video-decod.patch - patch_apply mfplat-streaming-support/0041-HACK-Switch-between-all-selection-streams-on-MF_SOUR.patch - patch_apply mfplat-streaming-support/0042-winegstreamer-Introduce-WMA-audio-decoder.patch - patch_apply mfplat-streaming-support/0043-Support-stereo-down-folding.patch - patch_apply mfplat-streaming-support/0044-winegstreamer-Implement-MF_SD_LANGUAGE.patch - patch_apply mfplat-streaming-support/0045-Revert-mf-topoloader-Add-a-structure-for-iterative-b.patch - patch_apply mfplat-streaming-support/0046-Revert-mf-topoloader-Clone-source-nodes-as-a-first-l.patch - patch_apply mfplat-streaming-support/0047-Revert-mf-topoloader-Switch-to-public-interface-for-.patch - patch_apply mfplat-streaming-support/0048-mf-Partially-implement-the-topology-loader.patch - patch_apply mfplat-streaming-support/0049-mf-Miscelaneous-fixes-to-topology-resolution.patch - patch_apply mfplat-streaming-support/0050-Rewrite-branch-resolver.patch - patch_apply mfplat-streaming-support/0051-mf-sar-Compare-against-native-media-type-in-IsMediaT.patch - patch_apply mfplat-streaming-support/0052-winegstreamer-Implement-audio-conversion-MFT.patch - patch_apply mfplat-streaming-support/0053-winegstreamer-Support-eAVEncH264VProfile_Constrained.patch - patch_apply mfplat-streaming-support/0054-winegstreamer-Support-older-versions.patch -fi - # Patchset mmsystem.dll16-MIDIHDR_Refcount # | # | This patchset fixes the following Wine bugs: diff --git a/staging/upstream-commit b/staging/upstream-commit index 259bb856..76338dbe 100644 --- a/staging/upstream-commit +++ b/staging/upstream-commit @@ -1 +1 @@ -2ee75bf9ade3e90f10ffe4236c8c95d817402392 +23c6dd55b8c983ec88cada0a6d6c75ee9cd93976