From 73351fd5931f1ee56cf8a646ac7853680644529f Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Sat, 3 Sep 2022 15:54:56 -0500 Subject: [PATCH] mfplat-streaming-support: Remove transform patches already implemented or superseded upstream. --- ...amer-Create-static-pads-on-wg_transf.patch | 223 ----- ...amer-Introduce-new-wg_transform-stru.patch | 293 ------ ...amer-Introduce-new-WG_MAJOR_TYPE_WMA.patch | 344 ------- ...amer-Move-format-helpers-to-a-dedica.patch | 933 ------------------ ...tivate-source-pad-in-push-mode-if-it.patch | 63 -- ...sh-stream-start-and-segment-events-i.patch | 60 -- ...er-Introduce-H.264-decoder-transform.patch | 391 -------- ...plement-GetInputAvailableType-for-de.patch | 158 --- ...plement-GetOutputAvailableType-for-d.patch | 57 -- ...plement-SetInputType-for-decode-tran.patch | 305 ------ ...plement-SetOutputType-for-decode-tra.patch | 116 --- ...plement-Get-Input-Output-StreamInfo-.patch | 106 -- ...mi-stub-GetAttributes-for-decoder-tr.patch | 30 - ...Register-the-H.264-decoder-transform.patch | 56 -- ...amer-Introduce-AAC-decoder-transform.patch | 214 ---- ...name-GStreamer-objects-to-be-more-ge.patch | 45 - ...plement-Get-Input-Output-StreamInfo-.patch | 73 -- ...mi-stub-Get-Attributes-functions-for.patch | 101 -- ...Introduce-color-conversion-transform.patch | 388 -------- ...plement-GetInputAvailableType-for-co.patch | 81 -- ...plement-SetInputType-for-color-conve.patch | 122 --- ...plement-GetOutputAvailableType-for-c.patch | 64 -- ...plement-SetOutputType-for-color-conv.patch | 153 --- ...plement-ProcessMessage-for-color-con.patch | 38 - ...plement-Get-Input-Output-StreamInfo-.patch | 95 -- ...ndle-flush-command-in-audio-converst.patch | 26 - ...plement-IMFTransform-GetOutputCurren.patch | 54 - ...er-Implement-stream-draining-support.patch | 178 ---- ...-Implement-unseekable-stream-support.patch | 436 -------- ...plement-Process-Input-Output-for-dec.patch | 676 ------------- ...plement-ProcessMessage-for-decoder-t.patch | 121 --- ...plement-Process-Input-Output-for-aud.patch | 485 --------- ...plement-Process-Input-Output-for-col.patch | 472 --------- ...plement-MFT_MESSAGE_COMMAND_FLUSH-fo.patch | 97 -- ...ed-full-buffer-in-audio-converter-Pr.patch | 48 - ...turn-S_OK-from-WMA-decoder-ProcessMe.patch | 29 - ...er-Introduce-new-wg_transform-struct.patch | 326 ------ ...troduce-new-wg_encoded_format-struct.patch | 185 ---- ...eate-static-pads-on-wg_transform-str.patch | 236 ----- ...okup-create-and-link-a-decoder-eleme.patch | 207 ---- ...nd-stream-start-and-caps-events-on-c.patch | 59 -- ...d-an-audioconverter-and-audioresampl.patch | 100 -- ...r-Implement-WMA-decoder-ProcessInput.patch | 249 ----- ...-Implement-WMA-decoder-ProcessOutput.patch | 407 -------- ...troduce-new-H264-decoder-transform-s.patch | 363 ------- ...turn-S_OK-from-H264-decoder-ProcessM.patch | 36 - ...-Implement-H264-decoder-SetInputType.patch | 89 -- ...plement-H264-decoder-GetOutputAvaila.patch | 196 ---- ...plement-H264-decoder-GetInputAvailab.patch | 56 -- ...Implement-H264-decoder-SetOutputType.patch | 93 -- ...plement-H264-decoder-GetInputStreamI.patch | 50 - ...plement-H264-decoder-GetOutputStream.patch | 55 -- ...d-H264-encoded-format-support-in-wg_.patch | 264 ----- ...-Implement-H264-decoder-ProcessInput.patch | 63 -- ...Implement-H264-decoder-ProcessOutput.patch | 83 -- ...d-timestamps-and-duration-to-H264-de.patch | 87 -- ...pport-dynamic-wg_transform-video-for.patch | 285 ------ ...e-an-optional-h264parse-wg_transform.patch | 44 - 58 files changed, 10664 deletions(-) delete mode 100644 patches/mfplat-streaming-support/0004-Revert-winegstreamer-Create-static-pads-on-wg_transf.patch delete mode 100644 patches/mfplat-streaming-support/0005-Revert-winegstreamer-Introduce-new-wg_transform-stru.patch delete mode 100644 patches/mfplat-streaming-support/0006-Revert-winegstreamer-Introduce-new-WG_MAJOR_TYPE_WMA.patch delete mode 100644 patches/mfplat-streaming-support/0007-Revert-winegstreamer-Move-format-helpers-to-a-dedica.patch delete mode 100644 patches/mfplat-streaming-support/0013-winegstreamer-Activate-source-pad-in-push-mode-if-it.patch delete mode 100644 patches/mfplat-streaming-support/0014-winegstreamer-Push-stream-start-and-segment-events-i.patch delete mode 100644 patches/mfplat-streaming-support/0015-winegstreamer-Introduce-H.264-decoder-transform.patch delete mode 100644 patches/mfplat-streaming-support/0016-winegstreamer-Implement-GetInputAvailableType-for-de.patch delete mode 100644 patches/mfplat-streaming-support/0017-winegstreamer-Implement-GetOutputAvailableType-for-d.patch delete mode 100644 patches/mfplat-streaming-support/0018-winegstreamer-Implement-SetInputType-for-decode-tran.patch delete mode 100644 patches/mfplat-streaming-support/0019-winegstreamer-Implement-SetOutputType-for-decode-tra.patch delete mode 100644 patches/mfplat-streaming-support/0020-winegstreamer-Implement-Get-Input-Output-StreamInfo-.patch delete mode 100644 patches/mfplat-streaming-support/0021-winegstreamer-Semi-stub-GetAttributes-for-decoder-tr.patch delete mode 100644 patches/mfplat-streaming-support/0022-winegstreamer-Register-the-H.264-decoder-transform.patch delete mode 100644 patches/mfplat-streaming-support/0023-winegstreamer-Introduce-AAC-decoder-transform.patch delete mode 100644 patches/mfplat-streaming-support/0024-winegstreamer-Rename-GStreamer-objects-to-be-more-ge.patch delete mode 100644 patches/mfplat-streaming-support/0026-winegstreamer-Implement-Get-Input-Output-StreamInfo-.patch delete mode 100644 patches/mfplat-streaming-support/0027-winegstreamer-Semi-stub-Get-Attributes-functions-for.patch delete mode 100644 patches/mfplat-streaming-support/0028-winegstreamer-Introduce-color-conversion-transform.patch delete mode 100644 patches/mfplat-streaming-support/0030-winegstreamer-Implement-GetInputAvailableType-for-co.patch delete mode 100644 patches/mfplat-streaming-support/0031-winegstreamer-Implement-SetInputType-for-color-conve.patch delete mode 100644 patches/mfplat-streaming-support/0032-winegstreamer-Implement-GetOutputAvailableType-for-c.patch delete mode 100644 patches/mfplat-streaming-support/0033-winegstreamer-Implement-SetOutputType-for-color-conv.patch delete mode 100644 patches/mfplat-streaming-support/0034-winegstreamer-Implement-ProcessMessage-for-color-con.patch delete mode 100644 patches/mfplat-streaming-support/0035-winegstreamer-Implement-Get-Input-Output-StreamInfo-.patch delete mode 100644 patches/mfplat-streaming-support/0037-winegstreamer-Handle-flush-command-in-audio-converst.patch delete mode 100644 patches/mfplat-streaming-support/0039-winegstreamer-Implement-IMFTransform-GetOutputCurren.patch delete mode 100644 patches/mfplat-streaming-support/0040-winegstreamer-Implement-stream-draining-support.patch delete mode 100644 patches/mfplat-streaming-support/0045-winegstreamer-Implement-unseekable-stream-support.patch delete mode 100644 patches/mfplat-streaming-support/0046-winegstreamer-Implement-Process-Input-Output-for-dec.patch delete mode 100644 patches/mfplat-streaming-support/0047-winegstreamer-Implement-ProcessMessage-for-decoder-t.patch delete mode 100644 patches/mfplat-streaming-support/0048-winegstreamer-Implement-Process-Input-Output-for-aud.patch delete mode 100644 patches/mfplat-streaming-support/0049-winegstreamer-Implement-Process-Input-Output-for-col.patch delete mode 100644 patches/mfplat-streaming-support/0051-winegstreamer-Implement-MFT_MESSAGE_COMMAND_FLUSH-fo.patch delete mode 100644 patches/mfplat-streaming-support/0054-winegstreamer-Feed-full-buffer-in-audio-converter-Pr.patch delete mode 100644 patches/mfplat-streaming-support/0056-winegstreamer-Return-S_OK-from-WMA-decoder-ProcessMe.patch delete mode 100644 patches/mfplat-streaming-support/0057-winegstreamer-Introduce-new-wg_transform-struct.patch delete mode 100644 patches/mfplat-streaming-support/0058-winegstreamer-Introduce-new-wg_encoded_format-struct.patch delete mode 100644 patches/mfplat-streaming-support/0059-winegstreamer-Create-static-pads-on-wg_transform-str.patch delete mode 100644 patches/mfplat-streaming-support/0060-winegstreamer-Lookup-create-and-link-a-decoder-eleme.patch delete mode 100644 patches/mfplat-streaming-support/0061-winegstreamer-Send-stream-start-and-caps-events-on-c.patch delete mode 100644 patches/mfplat-streaming-support/0062-winegstreamer-Add-an-audioconverter-and-audioresampl.patch delete mode 100644 patches/mfplat-streaming-support/0063-winegstreamer-Implement-WMA-decoder-ProcessInput.patch delete mode 100644 patches/mfplat-streaming-support/0064-winegstreamer-Implement-WMA-decoder-ProcessOutput.patch delete mode 100644 patches/mfplat-streaming-support/0066-winegstreamer-Introduce-new-H264-decoder-transform-s.patch delete mode 100644 patches/mfplat-streaming-support/0068-winegstreamer-Return-S_OK-from-H264-decoder-ProcessM.patch delete mode 100644 patches/mfplat-streaming-support/0069-winegstreamer-Implement-H264-decoder-SetInputType.patch delete mode 100644 patches/mfplat-streaming-support/0070-winegstreamer-Implement-H264-decoder-GetOutputAvaila.patch delete mode 100644 patches/mfplat-streaming-support/0071-winegstreamer-Implement-H264-decoder-GetInputAvailab.patch delete mode 100644 patches/mfplat-streaming-support/0072-winegstreamer-Implement-H264-decoder-SetOutputType.patch delete mode 100644 patches/mfplat-streaming-support/0073-winegstreamer-Implement-H264-decoder-GetInputStreamI.patch delete mode 100644 patches/mfplat-streaming-support/0074-winegstreamer-Implement-H264-decoder-GetOutputStream.patch delete mode 100644 patches/mfplat-streaming-support/0075-winegstreamer-Add-H264-encoded-format-support-in-wg_.patch delete mode 100644 patches/mfplat-streaming-support/0076-winegstreamer-Implement-H264-decoder-ProcessInput.patch delete mode 100644 patches/mfplat-streaming-support/0077-winegstreamer-Implement-H264-decoder-ProcessOutput.patch delete mode 100644 patches/mfplat-streaming-support/0078-winegstreamer-Add-timestamps-and-duration-to-H264-de.patch delete mode 100644 patches/mfplat-streaming-support/0079-winegstreamer-Support-dynamic-wg_transform-video-for.patch delete mode 100644 patches/mfplat-streaming-support/0081-winegstreamer-Use-an-optional-h264parse-wg_transform.patch diff --git a/patches/mfplat-streaming-support/0004-Revert-winegstreamer-Create-static-pads-on-wg_transf.patch b/patches/mfplat-streaming-support/0004-Revert-winegstreamer-Create-static-pads-on-wg_transf.patch deleted file mode 100644 index ef399691..00000000 --- a/patches/mfplat-streaming-support/0004-Revert-winegstreamer-Create-static-pads-on-wg_transf.patch +++ /dev/null @@ -1,223 +0,0 @@ -From fb5e9adb5eb72fa5d8369ec2e014985450432329 Mon Sep 17 00:00:00 2001 -From: Thomas Crider -Date: Sat, 19 Feb 2022 16:58:07 -0700 -Subject: [PATCH 04/88] Revert "winegstreamer: Create static pads on - wg_transform struct." - -This reverts commit 71bf5b24d7efabfcacfa707198efc4be0da3e446. ---- - dlls/winegstreamer/gst_private.h | 3 +- - dlls/winegstreamer/main.c | 9 ++---- - dlls/winegstreamer/unixlib.h | 2 -- - dlls/winegstreamer/wg_format.c | 40 ++---------------------- - dlls/winegstreamer/wg_transform.c | 51 +------------------------------ - dlls/winegstreamer/wma_decoder.c | 2 +- - 6 files changed, 7 insertions(+), 100 deletions(-) - -diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h -index a63daaf04b9..8bc9f838d29 100644 ---- a/dlls/winegstreamer/gst_private.h -+++ b/dlls/winegstreamer/gst_private.h -@@ -96,8 +96,7 @@ uint64_t wg_parser_stream_get_duration(struct wg_parser_stream *stream); - void wg_parser_stream_seek(struct wg_parser_stream *stream, double rate, - uint64_t start_pos, uint64_t stop_pos, DWORD start_flags, DWORD stop_flags); - --struct wg_transform *wg_transform_create(const struct wg_format *input_format, -- const struct wg_format *output_format); -+struct wg_transform *wg_transform_create(void); - void wg_transform_destroy(struct wg_transform *transform); - - unsigned int wg_format_get_max_size(const struct wg_format *format); -diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c -index 95b22abebb7..af5a691371d 100644 ---- a/dlls/winegstreamer/main.c -+++ b/dlls/winegstreamer/main.c -@@ -254,14 +254,9 @@ void wg_parser_stream_seek(struct wg_parser_stream *stream, double rate, - __wine_unix_call(unix_handle, unix_wg_parser_stream_seek, ¶ms); - } - --struct wg_transform *wg_transform_create(const struct wg_format *input_format, -- const struct wg_format *output_format) -+struct wg_transform *wg_transform_create(void) - { -- struct wg_transform_create_params params = -- { -- .input_format = input_format, -- .output_format = output_format, -- }; -+ struct wg_transform_create_params params = {0}; - - if (__wine_unix_call(unix_handle, unix_wg_transform_create, ¶ms)) - return NULL; -diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h -index 4adbb694766..8e3f5e84bfb 100644 ---- a/dlls/winegstreamer/unixlib.h -+++ b/dlls/winegstreamer/unixlib.h -@@ -232,8 +232,6 @@ struct wg_parser_stream_seek_params - struct wg_transform_create_params - { - struct wg_transform *transform; -- const struct wg_format *input_format; -- const struct wg_format *output_format; - }; - - enum unix_funcs -diff --git a/dlls/winegstreamer/wg_format.c b/dlls/winegstreamer/wg_format.c -index 40b9acfefff..8f771bb8abd 100644 ---- a/dlls/winegstreamer/wg_format.c -+++ b/dlls/winegstreamer/wg_format.c -@@ -394,43 +394,6 @@ static GstCaps *wg_format_to_caps_video(const struct wg_format *format) - return caps; - } - --static GstCaps *wg_format_to_caps_wma(const struct wg_format *format) --{ -- GstBuffer *buffer; -- GstCaps *caps; -- -- if (!(caps = gst_caps_new_empty_simple("audio/x-wma"))) -- return NULL; -- if (format->u.wma.version) -- gst_caps_set_simple(caps, "wmaversion", G_TYPE_INT, format->u.wma.version, NULL); -- -- if (format->u.wma.bitrate) -- gst_caps_set_simple(caps, "bitrate", G_TYPE_INT, format->u.wma.bitrate, NULL); -- if (format->u.wma.rate) -- gst_caps_set_simple(caps, "rate", G_TYPE_INT, format->u.wma.rate, NULL); -- if (format->u.wma.depth) -- gst_caps_set_simple(caps, "depth", G_TYPE_INT, format->u.wma.depth, NULL); -- if (format->u.wma.channels) -- gst_caps_set_simple(caps, "channels", G_TYPE_INT, format->u.wma.channels, NULL); -- if (format->u.wma.block_align) -- gst_caps_set_simple(caps, "block_align", G_TYPE_INT, format->u.wma.block_align, NULL); -- -- if (format->u.wma.codec_data_len) -- { -- if (!(buffer = gst_buffer_new_and_alloc(format->u.wma.codec_data_len))) -- { -- gst_caps_unref(caps); -- return NULL; -- } -- -- gst_buffer_fill(buffer, 0, format->u.wma.codec_data, format->u.wma.codec_data_len); -- gst_caps_set_simple(caps, "codec_data", GST_TYPE_BUFFER, buffer, NULL); -- gst_buffer_unref(buffer); -- } -- -- return caps; --} -- - GstCaps *wg_format_to_caps(const struct wg_format *format) - { - switch (format->major_type) -@@ -438,7 +401,8 @@ GstCaps *wg_format_to_caps(const struct wg_format *format) - case WG_MAJOR_TYPE_UNKNOWN: - return NULL; - case WG_MAJOR_TYPE_WMA: -- return wg_format_to_caps_wma(format); -+ GST_FIXME("WMA format not implemented!\n"); -+ return NULL; - case WG_MAJOR_TYPE_AUDIO: - return wg_format_to_caps_audio(format); - case WG_MAJOR_TYPE_VIDEO: -diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c -index e4545774428..2f225e5bc55 100644 ---- a/dlls/winegstreamer/wg_transform.c -+++ b/dlls/winegstreamer/wg_transform.c -@@ -44,29 +44,13 @@ GST_DEBUG_CATEGORY_EXTERN(wine); - - struct wg_transform - { -- GstPad *my_src, *my_sink; -+ int dummy; - }; - --static GstFlowReturn transform_sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *buffer) --{ -- struct wg_transform *transform = gst_pad_get_element_private(pad); -- -- GST_INFO("transform %p, buffer %p.", transform, buffer); -- -- gst_buffer_unref(buffer); -- -- return GST_FLOW_OK; --} -- - NTSTATUS wg_transform_destroy(void *args) - { - struct wg_transform *transform = args; - -- if (transform->my_sink) -- g_object_unref(transform->my_sink); -- if (transform->my_src) -- g_object_unref(transform->my_src); -- - free(transform); - return STATUS_SUCCESS; - } -@@ -74,10 +58,6 @@ NTSTATUS wg_transform_destroy(void *args) - NTSTATUS wg_transform_create(void *args) - { - struct wg_transform_create_params *params = args; -- struct wg_format output_format = *params->output_format; -- struct wg_format input_format = *params->input_format; -- GstCaps *src_caps = NULL, *sink_caps = NULL; -- GstPadTemplate *template = NULL; - struct wg_transform *transform; - NTSTATUS status; - -@@ -89,38 +69,9 @@ NTSTATUS wg_transform_create(void *args) - if (!(transform = calloc(1, sizeof(*transform)))) - goto done; - -- if (!(src_caps = wg_format_to_caps(&input_format))) -- goto done; -- if (!(sink_caps = wg_format_to_caps(&output_format))) -- goto done; -- -- if (!(template = gst_pad_template_new("src", GST_PAD_SRC, GST_PAD_ALWAYS, src_caps))) -- goto done; -- if (!(transform->my_src = gst_pad_new_from_template(template, "src"))) -- goto done; -- g_object_unref(template); -- template = NULL; -- -- if (!(template = gst_pad_template_new("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps))) -- goto done; -- if (!(transform->my_sink = gst_pad_new_from_template(template, "sink"))) -- goto done; -- g_object_unref(template); -- template = NULL; -- -- gst_pad_set_element_private(transform->my_sink, transform); -- gst_pad_set_chain_function(transform->my_sink, transform_sink_chain_cb); -- - status = STATUS_SUCCESS; - - done: -- if (template) -- g_object_unref(template); -- if (sink_caps) -- gst_caps_unref(sink_caps); -- if (src_caps) -- gst_caps_unref(src_caps); -- - if (status) - { - GST_ERROR("Failed to create winegstreamer transform."); -diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c -index 6c198706944..b14261706a7 100644 ---- a/dlls/winegstreamer/wma_decoder.c -+++ b/dlls/winegstreamer/wma_decoder.c -@@ -78,7 +78,7 @@ static HRESULT try_create_wg_transform(struct wma_decoder *decoder) - if (output_format.major_type == WG_MAJOR_TYPE_UNKNOWN) - return MF_E_INVALIDMEDIATYPE; - -- if (!(decoder->wg_transform = wg_transform_create(&input_format, &output_format))) -+ if (!(decoder->wg_transform = wg_transform_create())) - return E_FAIL; - - return S_OK; --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0005-Revert-winegstreamer-Introduce-new-wg_transform-stru.patch b/patches/mfplat-streaming-support/0005-Revert-winegstreamer-Introduce-new-wg_transform-stru.patch deleted file mode 100644 index 816c17c4..00000000 --- a/patches/mfplat-streaming-support/0005-Revert-winegstreamer-Introduce-new-wg_transform-stru.patch +++ /dev/null @@ -1,293 +0,0 @@ -From 51f5ec2a0fd00995b4ff155a89e46c7dff8e338b Mon Sep 17 00:00:00 2001 -From: Thomas Crider -Date: Sat, 19 Feb 2022 16:58:23 -0700 -Subject: [PATCH 05/88] Revert "winegstreamer: Introduce new wg_transform - struct." - -This reverts commit 51a262d368afca3ec1edf50a850dbd5339194280. ---- - dlls/winegstreamer/Makefile.in | 1 - - dlls/winegstreamer/gst_private.h | 3 -- - dlls/winegstreamer/main.c | 14 ----- - dlls/winegstreamer/unix_private.h | 5 -- - dlls/winegstreamer/unixlib.h | 8 --- - dlls/winegstreamer/wg_parser.c | 13 +---- - dlls/winegstreamer/wg_transform.c | 88 ------------------------------- - dlls/winegstreamer/wma_decoder.c | 11 ---- - 8 files changed, 2 insertions(+), 141 deletions(-) - delete mode 100644 dlls/winegstreamer/wg_transform.c - -diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in -index 0bcdb3eec65..d9805e3d797 100644 ---- a/dlls/winegstreamer/Makefile.in -+++ b/dlls/winegstreamer/Makefile.in -@@ -14,7 +14,6 @@ C_SRCS = \ - quartz_parser.c \ - wg_format.c \ - wg_parser.c \ -- wg_transform.c \ - wm_asyncreader.c \ - wm_reader.c \ - wm_syncreader.c \ -diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h -index 8bc9f838d29..3584f465218 100644 ---- a/dlls/winegstreamer/gst_private.h -+++ b/dlls/winegstreamer/gst_private.h -@@ -96,9 +96,6 @@ uint64_t wg_parser_stream_get_duration(struct wg_parser_stream *stream); - void wg_parser_stream_seek(struct wg_parser_stream *stream, double rate, - uint64_t start_pos, uint64_t stop_pos, DWORD start_flags, DWORD stop_flags); - --struct wg_transform *wg_transform_create(void); --void wg_transform_destroy(struct wg_transform *transform); -- - unsigned int wg_format_get_max_size(const struct wg_format *format); - - HRESULT avi_splitter_create(IUnknown *outer, IUnknown **out); -diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c -index af5a691371d..51a71d3b4a5 100644 ---- a/dlls/winegstreamer/main.c -+++ b/dlls/winegstreamer/main.c -@@ -254,20 +254,6 @@ void wg_parser_stream_seek(struct wg_parser_stream *stream, double rate, - __wine_unix_call(unix_handle, unix_wg_parser_stream_seek, ¶ms); - } - --struct wg_transform *wg_transform_create(void) --{ -- struct wg_transform_create_params params = {0}; -- -- if (__wine_unix_call(unix_handle, unix_wg_transform_create, ¶ms)) -- return NULL; -- return params.transform; --} -- --void wg_transform_destroy(struct wg_transform *transform) --{ -- __wine_unix_call(unix_handle, unix_wg_transform_destroy, transform); --} -- - BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved) - { - if (reason == DLL_PROCESS_ATTACH) -diff --git a/dlls/winegstreamer/unix_private.h b/dlls/winegstreamer/unix_private.h -index f9c4da2f6ea..b483638403d 100644 ---- a/dlls/winegstreamer/unix_private.h -+++ b/dlls/winegstreamer/unix_private.h -@@ -25,13 +25,8 @@ - - #include - --extern bool init_gstreamer(void) DECLSPEC_HIDDEN; -- - extern void wg_format_from_caps(struct wg_format *format, const GstCaps *caps) DECLSPEC_HIDDEN; - extern bool wg_format_compare(const struct wg_format *a, const struct wg_format *b) DECLSPEC_HIDDEN; - extern GstCaps *wg_format_to_caps(const struct wg_format *format) DECLSPEC_HIDDEN; - --extern NTSTATUS wg_transform_create(void *args) DECLSPEC_HIDDEN; --extern NTSTATUS wg_transform_destroy(void *args) DECLSPEC_HIDDEN; -- - #endif /* __WINE_WINEGSTREAMER_UNIX_PRIVATE_H */ -diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h -index 8e3f5e84bfb..45ec606fc6a 100644 ---- a/dlls/winegstreamer/unixlib.h -+++ b/dlls/winegstreamer/unixlib.h -@@ -229,11 +229,6 @@ struct wg_parser_stream_seek_params - DWORD start_flags, stop_flags; - }; - --struct wg_transform_create_params --{ -- struct wg_transform *transform; --}; -- - enum unix_funcs - { - unix_wg_parser_create, -@@ -262,9 +257,6 @@ enum unix_funcs - - unix_wg_parser_stream_get_duration, - unix_wg_parser_stream_seek, -- -- unix_wg_transform_create, -- unix_wg_transform_destroy, - }; - - #endif /* __WINE_WINEGSTREAMER_UNIXLIB_H */ -diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index 40c394c3caf..66f60d27477 100644 ---- a/dlls/winegstreamer/wg_parser.c -+++ b/dlls/winegstreamer/wg_parser.c -@@ -1586,13 +1586,6 @@ static void init_gstreamer_once(void) - gst_version_string(), GST_VERSION_MAJOR, GST_VERSION_MINOR, GST_VERSION_MICRO); - } - --bool init_gstreamer(void) --{ -- static pthread_once_t init_once = PTHREAD_ONCE_INIT; -- -- return !pthread_once(&init_once, init_gstreamer_once); --} -- - static NTSTATUS wg_parser_create(void *args) - { - static const init_gst_cb init_funcs[] = -@@ -1603,10 +1596,11 @@ static NTSTATUS wg_parser_create(void *args) - [WG_PARSER_WAVPARSE] = wave_parser_init_gst, - }; - -+ static pthread_once_t once = PTHREAD_ONCE_INIT; - struct wg_parser_create_params *params = args; - struct wg_parser *parser; - -- if (!init_gstreamer()) -+ if (pthread_once(&once, init_gstreamer_once)) - return E_FAIL; - - if (!(parser = calloc(1, sizeof(*parser)))) -@@ -1673,7 +1667,4 @@ const unixlib_entry_t __wine_unix_call_funcs[] = - - X(wg_parser_stream_get_duration), - X(wg_parser_stream_seek), -- -- X(wg_transform_create), -- X(wg_transform_destroy), - }; -diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c -deleted file mode 100644 -index 2f225e5bc55..00000000000 ---- a/dlls/winegstreamer/wg_transform.c -+++ /dev/null -@@ -1,88 +0,0 @@ --/* -- * GStreamer transform backend -- * -- * Copyright 2022 RĂ©mi Bernon for CodeWeavers -- * -- * This library is free software; you can redistribute it and/or -- * modify it under the terms of the GNU Lesser General Public -- * License as published by the Free Software Foundation; either -- * version 2.1 of the License, or (at your option) any later version. -- * -- * This library is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- * Lesser General Public License for more details. -- * -- * You should have received a copy of the GNU Lesser General Public -- * License along with this library; if not, write to the Free Software -- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -- */ -- --#if 0 --#pragma makedep unix --#endif -- --#include "config.h" -- --#include --#include --#include -- --#include --#include --#include -- --#include "ntstatus.h" --#define WIN32_NO_STATUS --#include "winternl.h" --#include "dshow.h" -- --#include "unix_private.h" -- --GST_DEBUG_CATEGORY_EXTERN(wine); --#define GST_CAT_DEFAULT wine -- --struct wg_transform --{ -- int dummy; --}; -- --NTSTATUS wg_transform_destroy(void *args) --{ -- struct wg_transform *transform = args; -- -- free(transform); -- return STATUS_SUCCESS; --} -- --NTSTATUS wg_transform_create(void *args) --{ -- struct wg_transform_create_params *params = args; -- struct wg_transform *transform; -- NTSTATUS status; -- -- if (!init_gstreamer()) -- return STATUS_UNSUCCESSFUL; -- -- status = STATUS_NO_MEMORY; -- -- if (!(transform = calloc(1, sizeof(*transform)))) -- goto done; -- -- status = STATUS_SUCCESS; -- --done: -- if (status) -- { -- GST_ERROR("Failed to create winegstreamer transform."); -- if (transform) -- wg_transform_destroy(transform); -- } -- else -- { -- GST_INFO("Created winegstreamer transform %p.", transform); -- params->transform = transform; -- } -- -- return status; --} -diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c -index b14261706a7..31f735a5b1d 100644 ---- a/dlls/winegstreamer/wma_decoder.c -+++ b/dlls/winegstreamer/wma_decoder.c -@@ -53,8 +53,6 @@ struct wma_decoder - LONG refcount; - IMFMediaType *input_type; - IMFMediaType *output_type; -- -- struct wg_transform *wg_transform; - }; - - static inline struct wma_decoder *impl_from_IUnknown(IUnknown *iface) -@@ -66,10 +64,6 @@ static HRESULT try_create_wg_transform(struct wma_decoder *decoder) - { - struct wg_format input_format, output_format; - -- if (decoder->wg_transform) -- wg_transform_destroy(decoder->wg_transform); -- decoder->wg_transform = NULL; -- - mf_media_type_to_wg_format(decoder->input_type, &input_format); - if (input_format.major_type == WG_MAJOR_TYPE_UNKNOWN) - return MF_E_INVALIDMEDIATYPE; -@@ -78,9 +72,6 @@ static HRESULT try_create_wg_transform(struct wma_decoder *decoder) - if (output_format.major_type == WG_MAJOR_TYPE_UNKNOWN) - return MF_E_INVALIDMEDIATYPE; - -- if (!(decoder->wg_transform = wg_transform_create())) -- return E_FAIL; -- - return S_OK; - } - -@@ -128,8 +119,6 @@ static ULONG WINAPI unknown_Release(IUnknown *iface) - - if (!refcount) - { -- if (decoder->wg_transform) -- wg_transform_destroy(decoder->wg_transform); - if (decoder->input_type) - IMFMediaType_Release(decoder->input_type); - if (decoder->output_type) --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0006-Revert-winegstreamer-Introduce-new-WG_MAJOR_TYPE_WMA.patch b/patches/mfplat-streaming-support/0006-Revert-winegstreamer-Introduce-new-WG_MAJOR_TYPE_WMA.patch deleted file mode 100644 index c69d0a6d..00000000 --- a/patches/mfplat-streaming-support/0006-Revert-winegstreamer-Introduce-new-WG_MAJOR_TYPE_WMA.patch +++ /dev/null @@ -1,344 +0,0 @@ -From 01b1caa979ab811edb7b859bc8f84ee68053a991 Mon Sep 17 00:00:00 2001 -From: Thomas Crider -Date: Sat, 19 Feb 2022 16:58:47 -0700 -Subject: [PATCH 06/88] Revert "winegstreamer: Introduce new WG_MAJOR_TYPE_WMA - major type." - -This reverts commit 76e2883c4ace29279dce8ea58787871046227b1a. ---- - dlls/winegstreamer/mfplat.c | 109 ++++++----------------------- - dlls/winegstreamer/quartz_parser.c | 8 --- - dlls/winegstreamer/unixlib.h | 12 ---- - dlls/winegstreamer/wg_format.c | 7 -- - dlls/winegstreamer/wm_reader.c | 8 --- - dlls/winegstreamer/wma_decoder.c | 18 ----- - 6 files changed, 21 insertions(+), 141 deletions(-) - -diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index 9b3fc429d32..a111bbe196d 100644 ---- a/dlls/winegstreamer/mfplat.c -+++ b/dlls/winegstreamer/mfplat.c -@@ -635,10 +635,6 @@ IMFMediaType *mf_media_type_from_wg_format(const struct wg_format *format) - case WG_MAJOR_TYPE_UNKNOWN: - return NULL; - -- case WG_MAJOR_TYPE_WMA: -- FIXME("WMA format not implemented!\n"); -- return NULL; -- - case WG_MAJOR_TYPE_AUDIO: - return mf_media_type_from_wg_format_audio(format); - -@@ -650,11 +646,17 @@ IMFMediaType *mf_media_type_from_wg_format(const struct wg_format *format) - return NULL; - } - --static void mf_media_type_to_wg_format_audio(IMFMediaType *type, const GUID *subtype, struct wg_format *format) -+static void mf_media_type_to_wg_format_audio(IMFMediaType *type, struct wg_format *format) - { - UINT32 rate, channels, channel_mask, depth; - unsigned int i; -+ GUID subtype; - -+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype))) -+ { -+ FIXME("Subtype is not set.\n"); -+ return; -+ } - if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &rate))) - { - FIXME("Sample rate is not set.\n"); -@@ -690,20 +692,26 @@ static void mf_media_type_to_wg_format_audio(IMFMediaType *type, const GUID *sub - - for (i = 0; i < ARRAY_SIZE(audio_formats); ++i) - { -- if (IsEqualGUID(subtype, audio_formats[i].subtype) && depth == audio_formats[i].depth) -+ if (IsEqualGUID(&subtype, audio_formats[i].subtype) && depth == audio_formats[i].depth) - { - format->u.audio.format = audio_formats[i].format; - return; - } - } -- FIXME("Unrecognized audio subtype %s, depth %u.\n", debugstr_guid(subtype), depth); -+ FIXME("Unrecognized audio subtype %s, depth %u.\n", debugstr_guid(&subtype), depth); - } - --static void mf_media_type_to_wg_format_video(IMFMediaType *type, const GUID *subtype, struct wg_format *format) -+static void mf_media_type_to_wg_format_video(IMFMediaType *type, struct wg_format *format) - { - UINT64 frame_rate, frame_size; - unsigned int i; -+ GUID subtype; - -+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype))) -+ { -+ FIXME("Subtype is not set.\n"); -+ return; -+ } - if (FAILED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size))) - { - FIXME("Frame size is not set.\n"); -@@ -724,80 +732,18 @@ static void mf_media_type_to_wg_format_video(IMFMediaType *type, const GUID *sub - - for (i = 0; i < ARRAY_SIZE(video_formats); ++i) - { -- if (IsEqualGUID(subtype, video_formats[i].subtype)) -+ if (IsEqualGUID(&subtype, video_formats[i].subtype)) - { - format->u.video.format = video_formats[i].format; - return; - } - } -- FIXME("Unrecognized video subtype %s.\n", debugstr_guid(subtype)); --} -- --static void mf_media_type_to_wg_format_wma(IMFMediaType *type, const GUID *subtype, struct wg_format *format) --{ -- UINT32 rate, depth, channels, block_align, bytes_per_second, codec_data_len; -- BYTE codec_data[64]; -- UINT32 version; -- -- if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &rate))) -- { -- FIXME("Sample rate is not set.\n"); -- return; -- } -- if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &channels))) -- { -- FIXME("Channel count is not set.\n"); -- return; -- } -- if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &block_align))) -- { -- FIXME("Block alignment is not set.\n"); -- return; -- } -- if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &depth))) -- { -- FIXME("Depth is not set.\n"); -- return; -- } -- if (FAILED(IMFMediaType_GetBlob(type, &MF_MT_USER_DATA, codec_data, sizeof(codec_data), &codec_data_len))) -- { -- FIXME("Codec data is not set.\n"); -- return; -- } -- if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &bytes_per_second))) -- { -- FIXME("Bitrate is not set.\n"); -- bytes_per_second = 0; -- } -- -- if (IsEqualGUID(subtype, &MEDIASUBTYPE_MSAUDIO1)) -- version = 1; -- else if (IsEqualGUID(subtype, &MFAudioFormat_WMAudioV8)) -- version = 2; -- else if (IsEqualGUID(subtype, &MFAudioFormat_WMAudioV9)) -- version = 3; -- else if (IsEqualGUID(subtype, &MFAudioFormat_WMAudio_Lossless)) -- version = 4; -- else -- { -- assert(0); -- return; -- } -- -- format->major_type = WG_MAJOR_TYPE_WMA; -- format->u.wma.version = version; -- format->u.wma.bitrate = bytes_per_second * 8; -- format->u.wma.rate = rate; -- format->u.wma.depth = depth; -- format->u.wma.channels = channels; -- format->u.wma.block_align = block_align; -- format->u.wma.codec_data_len = codec_data_len; -- memcpy(format->u.wma.codec_data, codec_data, codec_data_len); -+ FIXME("Unrecognized video subtype %s.\n", debugstr_guid(&subtype)); - } - - void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format) - { -- GUID major_type, subtype; -+ GUID major_type; - - memset(format, 0, sizeof(*format)); - -@@ -806,24 +752,11 @@ void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format) - FIXME("Major type is not set.\n"); - return; - } -- if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype))) -- { -- FIXME("Subtype is not set.\n"); -- return; -- } - - if (IsEqualGUID(&major_type, &MFMediaType_Audio)) -- { -- if (IsEqualGUID(&subtype, &MEDIASUBTYPE_MSAUDIO1) || -- IsEqualGUID(&subtype, &MFAudioFormat_WMAudioV8) || -- IsEqualGUID(&subtype, &MFAudioFormat_WMAudioV9) || -- IsEqualGUID(&subtype, &MFAudioFormat_WMAudio_Lossless)) -- mf_media_type_to_wg_format_wma(type, &subtype, format); -- else -- mf_media_type_to_wg_format_audio(type, &subtype, format); -- } -+ mf_media_type_to_wg_format_audio(type, format); - else if (IsEqualGUID(&major_type, &MFMediaType_Video)) -- mf_media_type_to_wg_format_video(type, &subtype, format); -+ mf_media_type_to_wg_format_video(type, format); - else - FIXME("Unrecognized major type %s.\n", debugstr_guid(&major_type)); - } -diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c -index e06c55ccfe0..45313ebda27 100644 ---- a/dlls/winegstreamer/quartz_parser.c -+++ b/dlls/winegstreamer/quartz_parser.c -@@ -319,10 +319,6 @@ unsigned int wg_format_get_max_size(const struct wg_format *format) - break; - } - -- case WG_MAJOR_TYPE_WMA: -- FIXME("WMA format not implemented!\n"); -- return 0; -- - case WG_MAJOR_TYPE_UNKNOWN: - FIXME("Cannot guess maximum sample size for unknown format.\n"); - return 0; -@@ -417,10 +413,6 @@ bool amt_from_wg_format(AM_MEDIA_TYPE *mt, const struct wg_format *format, bool - case WG_MAJOR_TYPE_UNKNOWN: - return false; - -- case WG_MAJOR_TYPE_WMA: -- FIXME("WMA format not implemented!\n"); -- return false; -- - case WG_MAJOR_TYPE_AUDIO: - return amt_from_wg_format_audio(mt, format); - -diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h -index 45ec606fc6a..82bb534b938 100644 ---- a/dlls/winegstreamer/unixlib.h -+++ b/dlls/winegstreamer/unixlib.h -@@ -37,7 +37,6 @@ struct wg_format - WG_MAJOR_TYPE_UNKNOWN, - WG_MAJOR_TYPE_VIDEO, - WG_MAJOR_TYPE_AUDIO, -- WG_MAJOR_TYPE_WMA, - } major_type; - - union -@@ -89,17 +88,6 @@ struct wg_format - uint32_t channel_mask; /* In WinMM format. */ - uint32_t rate; - } audio; -- struct -- { -- uint32_t version; -- uint32_t bitrate; -- uint32_t rate; -- uint32_t depth; -- uint32_t channels; -- uint32_t block_align; -- uint32_t codec_data_len; -- unsigned char codec_data[64]; -- } wma; - } u; - }; - -diff --git a/dlls/winegstreamer/wg_format.c b/dlls/winegstreamer/wg_format.c -index 8f771bb8abd..8952acc1c2e 100644 ---- a/dlls/winegstreamer/wg_format.c -+++ b/dlls/winegstreamer/wg_format.c -@@ -400,9 +400,6 @@ GstCaps *wg_format_to_caps(const struct wg_format *format) - { - case WG_MAJOR_TYPE_UNKNOWN: - return NULL; -- case WG_MAJOR_TYPE_WMA: -- GST_FIXME("WMA format not implemented!\n"); -- return NULL; - case WG_MAJOR_TYPE_AUDIO: - return wg_format_to_caps_audio(format); - case WG_MAJOR_TYPE_VIDEO: -@@ -422,10 +419,6 @@ bool wg_format_compare(const struct wg_format *a, const struct wg_format *b) - case WG_MAJOR_TYPE_UNKNOWN: - return false; - -- case WG_MAJOR_TYPE_WMA: -- GST_FIXME("WMA format not implemented!\n"); -- return false; -- - case WG_MAJOR_TYPE_AUDIO: - return a->u.audio.format == b->u.audio.format - && a->u.audio.channels == b->u.audio.channels -diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c -index 01518c6b9a8..d40afb66afd 100644 ---- a/dlls/winegstreamer/wm_reader.c -+++ b/dlls/winegstreamer/wm_reader.c -@@ -1687,9 +1687,6 @@ HRESULT wm_reader_get_output_format_count(struct wm_reader *reader, DWORD output - *count = ARRAY_SIZE(video_formats); - break; - -- case WG_MAJOR_TYPE_WMA: -- FIXME("WMA format not implemented!\n"); -- /* fallthrough */ - case WG_MAJOR_TYPE_AUDIO: - case WG_MAJOR_TYPE_UNKNOWN: - *count = 1; -@@ -1736,9 +1733,6 @@ HRESULT wm_reader_get_output_format(struct wm_reader *reader, DWORD output, - format.u.audio.format = WG_AUDIO_FORMAT_S16LE; - break; - -- case WG_MAJOR_TYPE_WMA: -- FIXME("WMA format not implemented!\n"); -- break; - case WG_MAJOR_TYPE_UNKNOWN: - break; - } -@@ -1814,8 +1808,6 @@ static const char *get_major_type_string(enum wg_major_type type) - return "video"; - case WG_MAJOR_TYPE_UNKNOWN: - return "unknown"; -- case WG_MAJOR_TYPE_WMA: -- return "wma"; - } - assert(0); - return NULL; -diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c -index 31f735a5b1d..78316059052 100644 ---- a/dlls/winegstreamer/wma_decoder.c -+++ b/dlls/winegstreamer/wma_decoder.c -@@ -60,21 +60,6 @@ static inline struct wma_decoder *impl_from_IUnknown(IUnknown *iface) - return CONTAINING_RECORD(iface, struct wma_decoder, IUnknown_inner); - } - --static HRESULT try_create_wg_transform(struct wma_decoder *decoder) --{ -- struct wg_format input_format, output_format; -- -- mf_media_type_to_wg_format(decoder->input_type, &input_format); -- if (input_format.major_type == WG_MAJOR_TYPE_UNKNOWN) -- return MF_E_INVALIDMEDIATYPE; -- -- mf_media_type_to_wg_format(decoder->output_type, &output_format); -- if (output_format.major_type == WG_MAJOR_TYPE_UNKNOWN) -- return MF_E_INVALIDMEDIATYPE; -- -- return S_OK; --} -- - static HRESULT WINAPI unknown_QueryInterface(IUnknown *iface, REFIID iid, void **out) - { - struct wma_decoder *decoder = impl_from_IUnknown(iface); -@@ -453,9 +438,6 @@ static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMF - if (FAILED(hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *)decoder->output_type))) - goto failed; - -- if (FAILED(hr = try_create_wg_transform(decoder))) -- goto failed; -- - return S_OK; - - failed: --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0007-Revert-winegstreamer-Move-format-helpers-to-a-dedica.patch b/patches/mfplat-streaming-support/0007-Revert-winegstreamer-Move-format-helpers-to-a-dedica.patch deleted file mode 100644 index de0fbecf..00000000 --- a/patches/mfplat-streaming-support/0007-Revert-winegstreamer-Move-format-helpers-to-a-dedica.patch +++ /dev/null @@ -1,933 +0,0 @@ -From 9f3feb4b3f4d3225e0733254fb673b675b975525 Mon Sep 17 00:00:00 2001 -From: Thomas Crider -Date: Sat, 19 Feb 2022 16:59:35 -0700 -Subject: [PATCH 07/88] Revert "winegstreamer: Move format helpers to a - dedicated source." - -This reverts commit a288b94831bcd9ef65c23475d8499e53fea69c18. ---- - dlls/winegstreamer/Makefile.in | 1 - - dlls/winegstreamer/unix_private.h | 32 --- - dlls/winegstreamer/wg_format.c | 436 ------------------------------ - dlls/winegstreamer/wg_parser.c | 397 ++++++++++++++++++++++++++- - 4 files changed, 395 insertions(+), 471 deletions(-) - delete mode 100644 dlls/winegstreamer/unix_private.h - delete mode 100644 dlls/winegstreamer/wg_format.c - -diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in -index d9805e3d797..c53e914e246 100644 ---- a/dlls/winegstreamer/Makefile.in -+++ b/dlls/winegstreamer/Makefile.in -@@ -12,7 +12,6 @@ C_SRCS = \ - media_source.c \ - mfplat.c \ - quartz_parser.c \ -- wg_format.c \ - wg_parser.c \ - wm_asyncreader.c \ - wm_reader.c \ -diff --git a/dlls/winegstreamer/unix_private.h b/dlls/winegstreamer/unix_private.h -deleted file mode 100644 -index b483638403d..00000000000 ---- a/dlls/winegstreamer/unix_private.h -+++ /dev/null -@@ -1,32 +0,0 @@ --/* -- * winegstreamer Unix library interface -- * -- * Copyright 2020-2021 Zebediah Figura for CodeWeavers -- * -- * This library is free software; you can redistribute it and/or -- * modify it under the terms of the GNU Lesser General Public -- * License as published by the Free Software Foundation; either -- * version 2.1 of the License, or (at your option) any later version. -- * -- * This library is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- * Lesser General Public License for more details. -- * -- * You should have received a copy of the GNU Lesser General Public -- * License along with this library; if not, write to the Free Software -- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -- */ -- --#ifndef __WINE_WINEGSTREAMER_UNIX_PRIVATE_H --#define __WINE_WINEGSTREAMER_UNIX_PRIVATE_H -- --#include "unixlib.h" -- --#include -- --extern void wg_format_from_caps(struct wg_format *format, const GstCaps *caps) DECLSPEC_HIDDEN; --extern bool wg_format_compare(const struct wg_format *a, const struct wg_format *b) DECLSPEC_HIDDEN; --extern GstCaps *wg_format_to_caps(const struct wg_format *format) DECLSPEC_HIDDEN; -- --#endif /* __WINE_WINEGSTREAMER_UNIX_PRIVATE_H */ -diff --git a/dlls/winegstreamer/wg_format.c b/dlls/winegstreamer/wg_format.c -deleted file mode 100644 -index 8952acc1c2e..00000000000 ---- a/dlls/winegstreamer/wg_format.c -+++ /dev/null -@@ -1,436 +0,0 @@ --/* -- * GStreamer format helpers -- * -- * Copyright 2010 Maarten Lankhorst for CodeWeavers -- * Copyright 2010 Aric Stewart for CodeWeavers -- * Copyright 2019-2020 Zebediah Figura -- * -- * This library is free software; you can redistribute it and/or -- * modify it under the terms of the GNU Lesser General Public -- * License as published by the Free Software Foundation; either -- * version 2.1 of the License, or (at your option) any later version. -- * -- * This library is distributed in the hope that it will be useful, -- * but WITHOUT ANY WARRANTY; without even the implied warranty of -- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -- * Lesser General Public License for more details. -- * -- * You should have received a copy of the GNU Lesser General Public -- * License along with this library; if not, write to the Free Software -- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -- */ -- --#if 0 --#pragma makedep unix --#endif -- --#include "config.h" -- --#include --#include --#include -- --#include --#include --#include -- --#include "winternl.h" --#include "dshow.h" -- --#include "unix_private.h" -- --GST_DEBUG_CATEGORY_EXTERN(wine); --#define GST_CAT_DEFAULT wine -- --static enum wg_audio_format wg_audio_format_from_gst(GstAudioFormat format) --{ -- switch (format) -- { -- case GST_AUDIO_FORMAT_U8: -- return WG_AUDIO_FORMAT_U8; -- case GST_AUDIO_FORMAT_S16LE: -- return WG_AUDIO_FORMAT_S16LE; -- case GST_AUDIO_FORMAT_S24LE: -- return WG_AUDIO_FORMAT_S24LE; -- case GST_AUDIO_FORMAT_S32LE: -- return WG_AUDIO_FORMAT_S32LE; -- case GST_AUDIO_FORMAT_F32LE: -- return WG_AUDIO_FORMAT_F32LE; -- case GST_AUDIO_FORMAT_F64LE: -- return WG_AUDIO_FORMAT_F64LE; -- default: -- return WG_AUDIO_FORMAT_UNKNOWN; -- } --} -- --static uint32_t wg_channel_position_from_gst(GstAudioChannelPosition position) --{ -- static const uint32_t position_map[] = -- { -- SPEAKER_FRONT_LEFT, -- SPEAKER_FRONT_RIGHT, -- SPEAKER_FRONT_CENTER, -- SPEAKER_LOW_FREQUENCY, -- SPEAKER_BACK_LEFT, -- SPEAKER_BACK_RIGHT, -- SPEAKER_FRONT_LEFT_OF_CENTER, -- SPEAKER_FRONT_RIGHT_OF_CENTER, -- SPEAKER_BACK_CENTER, -- 0, -- SPEAKER_SIDE_LEFT, -- SPEAKER_SIDE_RIGHT, -- SPEAKER_TOP_FRONT_LEFT, -- SPEAKER_TOP_FRONT_RIGHT, -- SPEAKER_TOP_FRONT_CENTER, -- SPEAKER_TOP_CENTER, -- SPEAKER_TOP_BACK_LEFT, -- SPEAKER_TOP_BACK_RIGHT, -- 0, -- 0, -- SPEAKER_TOP_BACK_CENTER, -- }; -- -- if (position == GST_AUDIO_CHANNEL_POSITION_MONO) -- return SPEAKER_FRONT_CENTER; -- -- if (position >= 0 && position < ARRAY_SIZE(position_map)) -- return position_map[position]; -- return 0; --} -- --static uint32_t wg_channel_mask_from_gst(const GstAudioInfo *info) --{ -- uint32_t mask = 0, position; -- unsigned int i; -- -- for (i = 0; i < GST_AUDIO_INFO_CHANNELS(info); ++i) -- { -- if (!(position = wg_channel_position_from_gst(GST_AUDIO_INFO_POSITION(info, i)))) -- { -- GST_WARNING("Unsupported channel %#x.", GST_AUDIO_INFO_POSITION(info, i)); -- return 0; -- } -- /* Make sure it's also in WinMM order. WinMM mandates that channels be -- * ordered, as it were, from least to most significant SPEAKER_* bit. -- * Hence we fail if the current channel was already specified, or if any -- * higher bit was already specified. */ -- if (mask & ~(position - 1)) -- { -- GST_WARNING("Unsupported channel order."); -- return 0; -- } -- mask |= position; -- } -- return mask; --} -- --static void wg_format_from_audio_info(struct wg_format *format, const GstAudioInfo *info) --{ -- format->major_type = WG_MAJOR_TYPE_AUDIO; -- format->u.audio.format = wg_audio_format_from_gst(GST_AUDIO_INFO_FORMAT(info)); -- format->u.audio.channels = GST_AUDIO_INFO_CHANNELS(info); -- format->u.audio.channel_mask = wg_channel_mask_from_gst(info); -- format->u.audio.rate = GST_AUDIO_INFO_RATE(info); --} -- --static enum wg_video_format wg_video_format_from_gst(GstVideoFormat format) --{ -- switch (format) -- { -- case GST_VIDEO_FORMAT_BGRA: -- return WG_VIDEO_FORMAT_BGRA; -- case GST_VIDEO_FORMAT_BGRx: -- return WG_VIDEO_FORMAT_BGRx; -- case GST_VIDEO_FORMAT_BGR: -- return WG_VIDEO_FORMAT_BGR; -- case GST_VIDEO_FORMAT_RGB15: -- return WG_VIDEO_FORMAT_RGB15; -- case GST_VIDEO_FORMAT_RGB16: -- return WG_VIDEO_FORMAT_RGB16; -- case GST_VIDEO_FORMAT_AYUV: -- return WG_VIDEO_FORMAT_AYUV; -- case GST_VIDEO_FORMAT_I420: -- return WG_VIDEO_FORMAT_I420; -- case GST_VIDEO_FORMAT_NV12: -- return WG_VIDEO_FORMAT_NV12; -- case GST_VIDEO_FORMAT_UYVY: -- return WG_VIDEO_FORMAT_UYVY; -- case GST_VIDEO_FORMAT_YUY2: -- return WG_VIDEO_FORMAT_YUY2; -- case GST_VIDEO_FORMAT_YV12: -- return WG_VIDEO_FORMAT_YV12; -- case GST_VIDEO_FORMAT_YVYU: -- return WG_VIDEO_FORMAT_YVYU; -- default: -- return WG_VIDEO_FORMAT_UNKNOWN; -- } --} -- --static void wg_format_from_video_info(struct wg_format *format, const GstVideoInfo *info) --{ -- format->major_type = WG_MAJOR_TYPE_VIDEO; -- format->u.video.format = wg_video_format_from_gst(GST_VIDEO_INFO_FORMAT(info)); -- format->u.video.width = GST_VIDEO_INFO_WIDTH(info); -- format->u.video.height = GST_VIDEO_INFO_HEIGHT(info); -- format->u.video.fps_n = GST_VIDEO_INFO_FPS_N(info); -- format->u.video.fps_d = GST_VIDEO_INFO_FPS_D(info); --} -- --static void wg_format_from_caps_audio_mpeg(struct wg_format *format, const GstCaps *caps) --{ -- const GstStructure *structure = gst_caps_get_structure(caps, 0); -- gint layer, channels, rate; -- -- if (!gst_structure_get_int(structure, "layer", &layer)) -- { -- GST_WARNING("Missing \"layer\" value."); -- return; -- } -- if (!gst_structure_get_int(structure, "channels", &channels)) -- { -- GST_WARNING("Missing \"channels\" value."); -- return; -- } -- if (!gst_structure_get_int(structure, "rate", &rate)) -- { -- GST_WARNING("Missing \"rate\" value."); -- return; -- } -- -- format->major_type = WG_MAJOR_TYPE_AUDIO; -- -- if (layer == 1) -- format->u.audio.format = WG_AUDIO_FORMAT_MPEG1_LAYER1; -- else if (layer == 2) -- format->u.audio.format = WG_AUDIO_FORMAT_MPEG1_LAYER2; -- else if (layer == 3) -- format->u.audio.format = WG_AUDIO_FORMAT_MPEG1_LAYER3; -- -- format->u.audio.channels = channels; -- format->u.audio.rate = rate; --} -- --static void wg_format_from_caps_video_cinepak(struct wg_format *format, const GstCaps *caps) --{ -- const GstStructure *structure = gst_caps_get_structure(caps, 0); -- gint width, height, fps_n, fps_d; -- -- if (!gst_structure_get_int(structure, "width", &width)) -- { -- GST_WARNING("Missing \"width\" value."); -- return; -- } -- if (!gst_structure_get_int(structure, "height", &height)) -- { -- GST_WARNING("Missing \"height\" value."); -- return; -- } -- if (!gst_structure_get_fraction(structure, "framerate", &fps_n, &fps_d)) -- { -- fps_n = 0; -- fps_d = 1; -- } -- -- format->major_type = WG_MAJOR_TYPE_VIDEO; -- format->u.video.format = WG_VIDEO_FORMAT_CINEPAK; -- format->u.video.width = width; -- format->u.video.height = height; -- format->u.video.fps_n = fps_n; -- format->u.video.fps_d = fps_d; --} -- --void wg_format_from_caps(struct wg_format *format, const GstCaps *caps) --{ -- const GstStructure *structure = gst_caps_get_structure(caps, 0); -- const char *name = gst_structure_get_name(structure); -- -- memset(format, 0, sizeof(*format)); -- -- if (!strcmp(name, "audio/x-raw")) -- { -- GstAudioInfo info; -- -- if (gst_audio_info_from_caps(&info, caps)) -- wg_format_from_audio_info(format, &info); -- } -- else if (!strcmp(name, "video/x-raw")) -- { -- GstVideoInfo info; -- -- if (gst_video_info_from_caps(&info, caps)) -- wg_format_from_video_info(format, &info); -- } -- else if (!strcmp(name, "audio/mpeg")) -- { -- wg_format_from_caps_audio_mpeg(format, caps); -- } -- else if (!strcmp(name, "video/x-cinepak")) -- { -- wg_format_from_caps_video_cinepak(format, caps); -- } -- else -- { -- gchar *str = gst_caps_to_string(caps); -- -- GST_FIXME("Unhandled caps %s.", str); -- g_free(str); -- } --} -- --static GstAudioFormat wg_audio_format_to_gst(enum wg_audio_format format) --{ -- switch (format) -- { -- case WG_AUDIO_FORMAT_U8: return GST_AUDIO_FORMAT_U8; -- case WG_AUDIO_FORMAT_S16LE: return GST_AUDIO_FORMAT_S16LE; -- case WG_AUDIO_FORMAT_S24LE: return GST_AUDIO_FORMAT_S24LE; -- case WG_AUDIO_FORMAT_S32LE: return GST_AUDIO_FORMAT_S32LE; -- case WG_AUDIO_FORMAT_F32LE: return GST_AUDIO_FORMAT_F32LE; -- case WG_AUDIO_FORMAT_F64LE: return GST_AUDIO_FORMAT_F64LE; -- default: return GST_AUDIO_FORMAT_UNKNOWN; -- } --} -- --static void wg_channel_mask_to_gst(GstAudioChannelPosition *positions, uint32_t mask, uint32_t channel_count) --{ -- const uint32_t orig_mask = mask; -- unsigned int i; -- DWORD bit; -- -- static const GstAudioChannelPosition position_map[] = -- { -- GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, -- GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, -- GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, -- GST_AUDIO_CHANNEL_POSITION_LFE1, -- GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, -- GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, -- GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, -- GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, -- GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, -- GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, -- GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, -- GST_AUDIO_CHANNEL_POSITION_TOP_CENTER, -- GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT, -- GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER, -- GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT, -- GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT, -- GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER, -- GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT, -- }; -- -- for (i = 0; i < channel_count; ++i) -- { -- positions[i] = GST_AUDIO_CHANNEL_POSITION_NONE; -- if (BitScanForward(&bit, mask)) -- { -- if (bit < ARRAY_SIZE(position_map)) -- positions[i] = position_map[bit]; -- else -- GST_WARNING("Invalid channel mask %#x.\n", orig_mask); -- mask &= ~(1 << bit); -- } -- else -- { -- GST_WARNING("Incomplete channel mask %#x.\n", orig_mask); -- } -- } --} -- --static GstCaps *wg_format_to_caps_audio(const struct wg_format *format) --{ -- GstAudioChannelPosition positions[32]; -- GstAudioFormat audio_format; -- GstAudioInfo info; -- -- if ((audio_format = wg_audio_format_to_gst(format->u.audio.format)) == GST_AUDIO_FORMAT_UNKNOWN) -- return NULL; -- -- wg_channel_mask_to_gst(positions, format->u.audio.channel_mask, format->u.audio.channels); -- gst_audio_info_set_format(&info, audio_format, format->u.audio.rate, format->u.audio.channels, positions); -- return gst_audio_info_to_caps(&info); --} -- --static GstVideoFormat wg_video_format_to_gst(enum wg_video_format format) --{ -- switch (format) -- { -- case WG_VIDEO_FORMAT_BGRA: return GST_VIDEO_FORMAT_BGRA; -- case WG_VIDEO_FORMAT_BGRx: return GST_VIDEO_FORMAT_BGRx; -- case WG_VIDEO_FORMAT_BGR: return GST_VIDEO_FORMAT_BGR; -- case WG_VIDEO_FORMAT_RGB15: return GST_VIDEO_FORMAT_RGB15; -- case WG_VIDEO_FORMAT_RGB16: return GST_VIDEO_FORMAT_RGB16; -- case WG_VIDEO_FORMAT_AYUV: return GST_VIDEO_FORMAT_AYUV; -- case WG_VIDEO_FORMAT_I420: return GST_VIDEO_FORMAT_I420; -- case WG_VIDEO_FORMAT_NV12: return GST_VIDEO_FORMAT_NV12; -- case WG_VIDEO_FORMAT_UYVY: return GST_VIDEO_FORMAT_UYVY; -- case WG_VIDEO_FORMAT_YUY2: return GST_VIDEO_FORMAT_YUY2; -- case WG_VIDEO_FORMAT_YV12: return GST_VIDEO_FORMAT_YV12; -- case WG_VIDEO_FORMAT_YVYU: return GST_VIDEO_FORMAT_YVYU; -- default: return GST_VIDEO_FORMAT_UNKNOWN; -- } --} -- --static GstCaps *wg_format_to_caps_video(const struct wg_format *format) --{ -- GstVideoFormat video_format; -- GstVideoInfo info; -- unsigned int i; -- GstCaps *caps; -- -- if ((video_format = wg_video_format_to_gst(format->u.video.format)) == GST_VIDEO_FORMAT_UNKNOWN) -- return NULL; -- -- gst_video_info_set_format(&info, video_format, format->u.video.width, abs(format->u.video.height)); -- if ((caps = gst_video_info_to_caps(&info))) -- { -- /* Clear some fields that shouldn't prevent us from connecting. */ -- for (i = 0; i < gst_caps_get_size(caps); ++i) -- { -- gst_structure_remove_fields(gst_caps_get_structure(caps, i), -- "framerate", "pixel-aspect-ratio", "colorimetry", "chroma-site", NULL); -- } -- } -- return caps; --} -- --GstCaps *wg_format_to_caps(const struct wg_format *format) --{ -- switch (format->major_type) -- { -- case WG_MAJOR_TYPE_UNKNOWN: -- return NULL; -- case WG_MAJOR_TYPE_AUDIO: -- return wg_format_to_caps_audio(format); -- case WG_MAJOR_TYPE_VIDEO: -- return wg_format_to_caps_video(format); -- } -- assert(0); -- return NULL; --} -- --bool wg_format_compare(const struct wg_format *a, const struct wg_format *b) --{ -- if (a->major_type != b->major_type) -- return false; -- -- switch (a->major_type) -- { -- case WG_MAJOR_TYPE_UNKNOWN: -- return false; -- -- case WG_MAJOR_TYPE_AUDIO: -- return a->u.audio.format == b->u.audio.format -- && a->u.audio.channels == b->u.audio.channels -- && a->u.audio.rate == b->u.audio.rate; -- -- case WG_MAJOR_TYPE_VIDEO: -- /* Do not compare FPS. */ -- return a->u.video.format == b->u.video.format -- && a->u.video.width == b->u.video.width -- && abs(a->u.video.height) == abs(b->u.video.height); -- } -- -- assert(0); -- return false; --} -diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index 66f60d27477..0a6cf927187 100644 ---- a/dlls/winegstreamer/wg_parser.c -+++ b/dlls/winegstreamer/wg_parser.c -@@ -37,7 +37,7 @@ - #include "winternl.h" - #include "dshow.h" - --#include "unix_private.h" -+#include "unixlib.h" - - typedef enum - { -@@ -51,7 +51,7 @@ typedef enum - * debug logging instead of Wine debug logging. In order to be safe we forbid - * any use of Wine debug logging in this entire file. */ - --GST_DEBUG_CATEGORY(wine); -+GST_DEBUG_CATEGORY_STATIC(wine); - #define GST_CAT_DEFAULT wine - - typedef BOOL (*init_gst_cb)(struct wg_parser *parser); -@@ -111,6 +111,399 @@ struct wg_parser_stream - uint64_t duration; - }; - -+static enum wg_audio_format wg_audio_format_from_gst(GstAudioFormat format) -+{ -+ switch (format) -+ { -+ case GST_AUDIO_FORMAT_U8: -+ return WG_AUDIO_FORMAT_U8; -+ case GST_AUDIO_FORMAT_S16LE: -+ return WG_AUDIO_FORMAT_S16LE; -+ case GST_AUDIO_FORMAT_S24LE: -+ return WG_AUDIO_FORMAT_S24LE; -+ case GST_AUDIO_FORMAT_S32LE: -+ return WG_AUDIO_FORMAT_S32LE; -+ case GST_AUDIO_FORMAT_F32LE: -+ return WG_AUDIO_FORMAT_F32LE; -+ case GST_AUDIO_FORMAT_F64LE: -+ return WG_AUDIO_FORMAT_F64LE; -+ default: -+ return WG_AUDIO_FORMAT_UNKNOWN; -+ } -+} -+ -+static uint32_t wg_channel_position_from_gst(GstAudioChannelPosition position) -+{ -+ static const uint32_t position_map[] = -+ { -+ SPEAKER_FRONT_LEFT, -+ SPEAKER_FRONT_RIGHT, -+ SPEAKER_FRONT_CENTER, -+ SPEAKER_LOW_FREQUENCY, -+ SPEAKER_BACK_LEFT, -+ SPEAKER_BACK_RIGHT, -+ SPEAKER_FRONT_LEFT_OF_CENTER, -+ SPEAKER_FRONT_RIGHT_OF_CENTER, -+ SPEAKER_BACK_CENTER, -+ 0, -+ SPEAKER_SIDE_LEFT, -+ SPEAKER_SIDE_RIGHT, -+ SPEAKER_TOP_FRONT_LEFT, -+ SPEAKER_TOP_FRONT_RIGHT, -+ SPEAKER_TOP_FRONT_CENTER, -+ SPEAKER_TOP_CENTER, -+ SPEAKER_TOP_BACK_LEFT, -+ SPEAKER_TOP_BACK_RIGHT, -+ 0, -+ 0, -+ SPEAKER_TOP_BACK_CENTER, -+ }; -+ -+ if (position == GST_AUDIO_CHANNEL_POSITION_MONO) -+ return SPEAKER_FRONT_CENTER; -+ -+ if (position >= 0 && position < ARRAY_SIZE(position_map)) -+ return position_map[position]; -+ return 0; -+} -+ -+static uint32_t wg_channel_mask_from_gst(const GstAudioInfo *info) -+{ -+ uint32_t mask = 0, position; -+ unsigned int i; -+ -+ for (i = 0; i < GST_AUDIO_INFO_CHANNELS(info); ++i) -+ { -+ if (!(position = wg_channel_position_from_gst(GST_AUDIO_INFO_POSITION(info, i)))) -+ { -+ GST_WARNING("Unsupported channel %#x.", GST_AUDIO_INFO_POSITION(info, i)); -+ return 0; -+ } -+ /* Make sure it's also in WinMM order. WinMM mandates that channels be -+ * ordered, as it were, from least to most significant SPEAKER_* bit. -+ * Hence we fail if the current channel was already specified, or if any -+ * higher bit was already specified. */ -+ if (mask & ~(position - 1)) -+ { -+ GST_WARNING("Unsupported channel order."); -+ return 0; -+ } -+ mask |= position; -+ } -+ return mask; -+} -+ -+static void wg_format_from_audio_info(struct wg_format *format, const GstAudioInfo *info) -+{ -+ format->major_type = WG_MAJOR_TYPE_AUDIO; -+ format->u.audio.format = wg_audio_format_from_gst(GST_AUDIO_INFO_FORMAT(info)); -+ format->u.audio.channels = GST_AUDIO_INFO_CHANNELS(info); -+ format->u.audio.channel_mask = wg_channel_mask_from_gst(info); -+ format->u.audio.rate = GST_AUDIO_INFO_RATE(info); -+} -+ -+static enum wg_video_format wg_video_format_from_gst(GstVideoFormat format) -+{ -+ switch (format) -+ { -+ case GST_VIDEO_FORMAT_BGRA: -+ return WG_VIDEO_FORMAT_BGRA; -+ case GST_VIDEO_FORMAT_BGRx: -+ return WG_VIDEO_FORMAT_BGRx; -+ case GST_VIDEO_FORMAT_BGR: -+ return WG_VIDEO_FORMAT_BGR; -+ case GST_VIDEO_FORMAT_RGB15: -+ return WG_VIDEO_FORMAT_RGB15; -+ case GST_VIDEO_FORMAT_RGB16: -+ return WG_VIDEO_FORMAT_RGB16; -+ case GST_VIDEO_FORMAT_AYUV: -+ return WG_VIDEO_FORMAT_AYUV; -+ case GST_VIDEO_FORMAT_I420: -+ return WG_VIDEO_FORMAT_I420; -+ case GST_VIDEO_FORMAT_NV12: -+ return WG_VIDEO_FORMAT_NV12; -+ case GST_VIDEO_FORMAT_UYVY: -+ return WG_VIDEO_FORMAT_UYVY; -+ case GST_VIDEO_FORMAT_YUY2: -+ return WG_VIDEO_FORMAT_YUY2; -+ case GST_VIDEO_FORMAT_YV12: -+ return WG_VIDEO_FORMAT_YV12; -+ case GST_VIDEO_FORMAT_YVYU: -+ return WG_VIDEO_FORMAT_YVYU; -+ default: -+ return WG_VIDEO_FORMAT_UNKNOWN; -+ } -+} -+ -+static void wg_format_from_video_info(struct wg_format *format, const GstVideoInfo *info) -+{ -+ format->major_type = WG_MAJOR_TYPE_VIDEO; -+ format->u.video.format = wg_video_format_from_gst(GST_VIDEO_INFO_FORMAT(info)); -+ format->u.video.width = GST_VIDEO_INFO_WIDTH(info); -+ format->u.video.height = GST_VIDEO_INFO_HEIGHT(info); -+ format->u.video.fps_n = GST_VIDEO_INFO_FPS_N(info); -+ format->u.video.fps_d = GST_VIDEO_INFO_FPS_D(info); -+} -+ -+static void wg_format_from_caps_audio_mpeg(struct wg_format *format, const GstCaps *caps) -+{ -+ const GstStructure *structure = gst_caps_get_structure(caps, 0); -+ gint layer, channels, rate; -+ -+ if (!gst_structure_get_int(structure, "layer", &layer)) -+ { -+ GST_WARNING("Missing \"layer\" value."); -+ return; -+ } -+ if (!gst_structure_get_int(structure, "channels", &channels)) -+ { -+ GST_WARNING("Missing \"channels\" value."); -+ return; -+ } -+ if (!gst_structure_get_int(structure, "rate", &rate)) -+ { -+ GST_WARNING("Missing \"rate\" value."); -+ return; -+ } -+ -+ format->major_type = WG_MAJOR_TYPE_AUDIO; -+ -+ if (layer == 1) -+ format->u.audio.format = WG_AUDIO_FORMAT_MPEG1_LAYER1; -+ else if (layer == 2) -+ format->u.audio.format = WG_AUDIO_FORMAT_MPEG1_LAYER2; -+ else if (layer == 3) -+ format->u.audio.format = WG_AUDIO_FORMAT_MPEG1_LAYER3; -+ -+ format->u.audio.channels = channels; -+ format->u.audio.rate = rate; -+} -+ -+static void wg_format_from_caps_video_cinepak(struct wg_format *format, const GstCaps *caps) -+{ -+ const GstStructure *structure = gst_caps_get_structure(caps, 0); -+ gint width, height, fps_n, fps_d; -+ -+ if (!gst_structure_get_int(structure, "width", &width)) -+ { -+ GST_WARNING("Missing \"width\" value."); -+ return; -+ } -+ if (!gst_structure_get_int(structure, "height", &height)) -+ { -+ GST_WARNING("Missing \"height\" value."); -+ return; -+ } -+ if (!gst_structure_get_fraction(structure, "framerate", &fps_n, &fps_d)) -+ { -+ fps_n = 0; -+ fps_d = 1; -+ } -+ -+ format->major_type = WG_MAJOR_TYPE_VIDEO; -+ format->u.video.format = WG_VIDEO_FORMAT_CINEPAK; -+ format->u.video.width = width; -+ format->u.video.height = height; -+ format->u.video.fps_n = fps_n; -+ format->u.video.fps_d = fps_d; -+} -+ -+static void wg_format_from_caps(struct wg_format *format, const GstCaps *caps) -+{ -+ const GstStructure *structure = gst_caps_get_structure(caps, 0); -+ const char *name = gst_structure_get_name(structure); -+ -+ memset(format, 0, sizeof(*format)); -+ -+ if (!strcmp(name, "audio/x-raw")) -+ { -+ GstAudioInfo info; -+ -+ if (gst_audio_info_from_caps(&info, caps)) -+ wg_format_from_audio_info(format, &info); -+ } -+ else if (!strcmp(name, "video/x-raw")) -+ { -+ GstVideoInfo info; -+ -+ if (gst_video_info_from_caps(&info, caps)) -+ wg_format_from_video_info(format, &info); -+ } -+ else if (!strcmp(name, "audio/mpeg")) -+ { -+ wg_format_from_caps_audio_mpeg(format, caps); -+ } -+ else if (!strcmp(name, "video/x-cinepak")) -+ { -+ wg_format_from_caps_video_cinepak(format, caps); -+ } -+ else -+ { -+ gchar *str = gst_caps_to_string(caps); -+ -+ GST_FIXME("Unhandled caps %s.", str); -+ g_free(str); -+ } -+} -+ -+static GstAudioFormat wg_audio_format_to_gst(enum wg_audio_format format) -+{ -+ switch (format) -+ { -+ case WG_AUDIO_FORMAT_U8: return GST_AUDIO_FORMAT_U8; -+ case WG_AUDIO_FORMAT_S16LE: return GST_AUDIO_FORMAT_S16LE; -+ case WG_AUDIO_FORMAT_S24LE: return GST_AUDIO_FORMAT_S24LE; -+ case WG_AUDIO_FORMAT_S32LE: return GST_AUDIO_FORMAT_S32LE; -+ case WG_AUDIO_FORMAT_F32LE: return GST_AUDIO_FORMAT_F32LE; -+ case WG_AUDIO_FORMAT_F64LE: return GST_AUDIO_FORMAT_F64LE; -+ default: return GST_AUDIO_FORMAT_UNKNOWN; -+ } -+} -+ -+static void wg_channel_mask_to_gst(GstAudioChannelPosition *positions, uint32_t mask, uint32_t channel_count) -+{ -+ const uint32_t orig_mask = mask; -+ unsigned int i; -+ DWORD bit; -+ -+ static const GstAudioChannelPosition position_map[] = -+ { -+ GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT, -+ GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT, -+ GST_AUDIO_CHANNEL_POSITION_FRONT_CENTER, -+ GST_AUDIO_CHANNEL_POSITION_LFE1, -+ GST_AUDIO_CHANNEL_POSITION_REAR_LEFT, -+ GST_AUDIO_CHANNEL_POSITION_REAR_RIGHT, -+ GST_AUDIO_CHANNEL_POSITION_FRONT_LEFT_OF_CENTER, -+ GST_AUDIO_CHANNEL_POSITION_FRONT_RIGHT_OF_CENTER, -+ GST_AUDIO_CHANNEL_POSITION_REAR_CENTER, -+ GST_AUDIO_CHANNEL_POSITION_SIDE_LEFT, -+ GST_AUDIO_CHANNEL_POSITION_SIDE_RIGHT, -+ GST_AUDIO_CHANNEL_POSITION_TOP_CENTER, -+ GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_LEFT, -+ GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_CENTER, -+ GST_AUDIO_CHANNEL_POSITION_TOP_FRONT_RIGHT, -+ GST_AUDIO_CHANNEL_POSITION_TOP_REAR_LEFT, -+ GST_AUDIO_CHANNEL_POSITION_TOP_REAR_CENTER, -+ GST_AUDIO_CHANNEL_POSITION_TOP_REAR_RIGHT, -+ }; -+ -+ for (i = 0; i < channel_count; ++i) -+ { -+ positions[i] = GST_AUDIO_CHANNEL_POSITION_NONE; -+ if (BitScanForward(&bit, mask)) -+ { -+ if (bit < ARRAY_SIZE(position_map)) -+ positions[i] = position_map[bit]; -+ else -+ GST_WARNING("Invalid channel mask %#x.\n", orig_mask); -+ mask &= ~(1 << bit); -+ } -+ else -+ { -+ GST_WARNING("Incomplete channel mask %#x.\n", orig_mask); -+ } -+ } -+} -+ -+static GstCaps *wg_format_to_caps_audio(const struct wg_format *format) -+{ -+ GstAudioChannelPosition positions[32]; -+ GstAudioFormat audio_format; -+ GstAudioInfo info; -+ -+ if ((audio_format = wg_audio_format_to_gst(format->u.audio.format)) == GST_AUDIO_FORMAT_UNKNOWN) -+ return NULL; -+ -+ wg_channel_mask_to_gst(positions, format->u.audio.channel_mask, format->u.audio.channels); -+ gst_audio_info_set_format(&info, audio_format, format->u.audio.rate, format->u.audio.channels, positions); -+ return gst_audio_info_to_caps(&info); -+} -+ -+static GstVideoFormat wg_video_format_to_gst(enum wg_video_format format) -+{ -+ switch (format) -+ { -+ case WG_VIDEO_FORMAT_BGRA: return GST_VIDEO_FORMAT_BGRA; -+ case WG_VIDEO_FORMAT_BGRx: return GST_VIDEO_FORMAT_BGRx; -+ case WG_VIDEO_FORMAT_BGR: return GST_VIDEO_FORMAT_BGR; -+ case WG_VIDEO_FORMAT_RGB15: return GST_VIDEO_FORMAT_RGB15; -+ case WG_VIDEO_FORMAT_RGB16: return GST_VIDEO_FORMAT_RGB16; -+ case WG_VIDEO_FORMAT_AYUV: return GST_VIDEO_FORMAT_AYUV; -+ case WG_VIDEO_FORMAT_I420: return GST_VIDEO_FORMAT_I420; -+ case WG_VIDEO_FORMAT_NV12: return GST_VIDEO_FORMAT_NV12; -+ case WG_VIDEO_FORMAT_UYVY: return GST_VIDEO_FORMAT_UYVY; -+ case WG_VIDEO_FORMAT_YUY2: return GST_VIDEO_FORMAT_YUY2; -+ case WG_VIDEO_FORMAT_YV12: return GST_VIDEO_FORMAT_YV12; -+ case WG_VIDEO_FORMAT_YVYU: return GST_VIDEO_FORMAT_YVYU; -+ default: return GST_VIDEO_FORMAT_UNKNOWN; -+ } -+} -+ -+static GstCaps *wg_format_to_caps_video(const struct wg_format *format) -+{ -+ GstVideoFormat video_format; -+ GstVideoInfo info; -+ unsigned int i; -+ GstCaps *caps; -+ -+ if ((video_format = wg_video_format_to_gst(format->u.video.format)) == GST_VIDEO_FORMAT_UNKNOWN) -+ return NULL; -+ -+ gst_video_info_set_format(&info, video_format, format->u.video.width, abs(format->u.video.height)); -+ if ((caps = gst_video_info_to_caps(&info))) -+ { -+ /* Clear some fields that shouldn't prevent us from connecting. */ -+ for (i = 0; i < gst_caps_get_size(caps); ++i) -+ { -+ gst_structure_remove_fields(gst_caps_get_structure(caps, i), -+ "framerate", "pixel-aspect-ratio", "colorimetry", "chroma-site", NULL); -+ } -+ } -+ return caps; -+} -+ -+static GstCaps *wg_format_to_caps(const struct wg_format *format) -+{ -+ switch (format->major_type) -+ { -+ case WG_MAJOR_TYPE_UNKNOWN: -+ return NULL; -+ case WG_MAJOR_TYPE_AUDIO: -+ return wg_format_to_caps_audio(format); -+ case WG_MAJOR_TYPE_VIDEO: -+ return wg_format_to_caps_video(format); -+ } -+ assert(0); -+ return NULL; -+} -+ -+static bool wg_format_compare(const struct wg_format *a, const struct wg_format *b) -+{ -+ if (a->major_type != b->major_type) -+ return false; -+ -+ switch (a->major_type) -+ { -+ case WG_MAJOR_TYPE_UNKNOWN: -+ return false; -+ -+ case WG_MAJOR_TYPE_AUDIO: -+ return a->u.audio.format == b->u.audio.format -+ && a->u.audio.channels == b->u.audio.channels -+ && a->u.audio.rate == b->u.audio.rate; -+ -+ case WG_MAJOR_TYPE_VIDEO: -+ /* Do not compare FPS. */ -+ return a->u.video.format == b->u.video.format -+ && a->u.video.width == b->u.video.width -+ && abs(a->u.video.height) == abs(b->u.video.height); -+ } -+ -+ assert(0); -+ return false; -+} -+ - static NTSTATUS wg_parser_get_stream_count(void *args) - { - struct wg_parser_get_stream_count_params *params = args; --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0013-winegstreamer-Activate-source-pad-in-push-mode-if-it.patch b/patches/mfplat-streaming-support/0013-winegstreamer-Activate-source-pad-in-push-mode-if-it.patch deleted file mode 100644 index 85a9d738..00000000 --- a/patches/mfplat-streaming-support/0013-winegstreamer-Activate-source-pad-in-push-mode-if-it.patch +++ /dev/null @@ -1,63 +0,0 @@ -From 75d383ab1c6b3c3872b895164c816d11de1d821c Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Tue, 9 Mar 2021 16:53:09 -0500 -Subject: [PATCH 13/88] winegstreamer: Activate source pad in push mode if it - isn't activated in pull mode. - -Since our source pad is not part of any element, gstreamer won't end up activating it -directly through the state transition. Instead, if the downstream element doesn't -activate the source pad into pull mode during the transition to the READY state, -we activate our pad in push mode. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/wg_parser.c | 9 ++++++++- - 1 file changed, 8 insertions(+), 1 deletion(-) - -diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index b93b2c182ae..d7412409a27 100644 ---- a/dlls/winegstreamer/wg_parser.c -+++ b/dlls/winegstreamer/wg_parser.c -@@ -75,7 +75,7 @@ struct wg_parser - pthread_mutex_t mutex; - - pthread_cond_t init_cond; -- bool no_more_pads, has_duration, error; -+ bool no_more_pads, has_duration, error, pull_mode; - - pthread_cond_t read_cond, read_done_cond; - struct -@@ -1528,9 +1528,12 @@ static gboolean src_activate_mode_cb(GstPad *pad, GstObject *parent, GstPadMode - GST_DEBUG("%s source pad for parser %p in %s mode.", - activate ? "Activating" : "Deactivating", parser, gst_pad_mode_get_name(mode)); - -+ parser->pull_mode = false; -+ - switch (mode) - { - case GST_PAD_MODE_PULL: -+ parser->pull_mode = activate; - return TRUE; - case GST_PAD_MODE_PUSH: - return activate_push(pad, activate); -@@ -1695,6 +1698,8 @@ static NTSTATUS wg_parser_connect(void *args) - goto out; - - gst_element_set_state(parser->container, GST_STATE_PAUSED); -+ if (!parser->pull_mode) -+ gst_pad_set_active(parser->my_src, 1); - ret = gst_element_get_state(parser->container, NULL, NULL, -1); - if (ret == GST_STATE_CHANGE_FAILURE) - { -@@ -1833,6 +1838,8 @@ static NTSTATUS wg_parser_disconnect(void *args) - pthread_mutex_unlock(&parser->mutex); - - gst_element_set_state(parser->container, GST_STATE_NULL); -+ if (!parser->pull_mode) -+ gst_pad_set_active(parser->my_src, 0); - gst_pad_unlink(parser->my_src, parser->their_sink); - gst_object_unref(parser->my_src); - gst_object_unref(parser->their_sink); --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0014-winegstreamer-Push-stream-start-and-segment-events-i.patch b/patches/mfplat-streaming-support/0014-winegstreamer-Push-stream-start-and-segment-events-i.patch deleted file mode 100644 index 83158c7e..00000000 --- a/patches/mfplat-streaming-support/0014-winegstreamer-Push-stream-start-and-segment-events-i.patch +++ /dev/null @@ -1,60 +0,0 @@ -From c8a074d72e06a8e44cb9390126e656800d249e08 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Wed, 10 Mar 2021 10:43:03 -0500 -Subject: [PATCH 14/88] winegstreamer: Push stream-start and segment events in - push mode. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/wg_parser.c | 13 +++++++++++++ - 1 file changed, 13 insertions(+) - -diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index d7412409a27..c6e8bbcb26b 100644 ---- a/dlls/winegstreamer/wg_parser.c -+++ b/dlls/winegstreamer/wg_parser.c -@@ -1449,6 +1449,7 @@ static void *push_data(void *arg) - { - struct wg_parser *parser = arg; - GstBuffer *buffer; -+ GstSegment *segment; - guint max_size; - - GST_DEBUG("Starting push thread."); -@@ -1461,6 +1462,12 @@ static void *push_data(void *arg) - - max_size = parser->stop_offset ? parser->stop_offset : parser->file_size; - -+ gst_pad_push_event(parser->my_src, gst_event_new_stream_start("wg_stream")); -+ -+ segment = gst_segment_new(); -+ gst_segment_init(segment, GST_FORMAT_BYTES); -+ gst_pad_push_event(parser->my_src, gst_event_new_segment(segment)); -+ - for (;;) - { - ULONG size; -@@ -1595,6 +1602,7 @@ static gboolean src_perform_seek(struct wg_parser *parser, GstEvent *event) - GstEvent *flush_event; - GstSeekFlags flags; - gint64 cur, stop; -+ GstSegment *seg; - guint32 seqnum; - gdouble rate; - -@@ -1628,7 +1636,12 @@ static gboolean src_perform_seek(struct wg_parser *parser, GstEvent *event) - gst_event_set_seqnum(flush_event, seqnum); - gst_pad_push_event(parser->my_src, flush_event); - if (thread) -+ { - gst_pad_set_active(parser->my_src, 1); -+ seg = gst_segment_new(); -+ gst_segment_init(seg, GST_FORMAT_BYTES); -+ gst_pad_push_event(parser->my_src, gst_event_new_segment(seg)); -+ } - } - - return TRUE; --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0015-winegstreamer-Introduce-H.264-decoder-transform.patch b/patches/mfplat-streaming-support/0015-winegstreamer-Introduce-H.264-decoder-transform.patch deleted file mode 100644 index 34f26582..00000000 --- a/patches/mfplat-streaming-support/0015-winegstreamer-Introduce-H.264-decoder-transform.patch +++ /dev/null @@ -1,391 +0,0 @@ -From 95180a07deb9e543627a8705da2bc73ccfff70a5 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Wed, 10 Mar 2021 13:09:51 -0500 -Subject: [PATCH 15/88] winegstreamer: Introduce H.264 decoder transform. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/Makefile.in | 1 + - dlls/winegstreamer/decode_transform.c | 301 +++++++++++++++++++ - dlls/winegstreamer/gst_private.h | 2 + - dlls/winegstreamer/main.c | 3 + - dlls/winegstreamer/mfplat.c | 1 + - dlls/winegstreamer/winegstreamer_classes.idl | 6 + - 6 files changed, 314 insertions(+) - create mode 100644 dlls/winegstreamer/decode_transform.c - -diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in -index c53e914e246..3da8c614ed2 100644 ---- a/dlls/winegstreamer/Makefile.in -+++ b/dlls/winegstreamer/Makefile.in -@@ -8,6 +8,7 @@ EXTRALIBS = $(GSTREAMER_LIBS) $(PTHREAD_LIBS) - - C_SRCS = \ - audioconvert.c \ -+ decode_transform.c \ - main.c \ - media_source.c \ - mfplat.c \ -diff --git a/dlls/winegstreamer/decode_transform.c b/dlls/winegstreamer/decode_transform.c -new file mode 100644 -index 00000000000..f5d4763bde4 ---- /dev/null -+++ b/dlls/winegstreamer/decode_transform.c -@@ -0,0 +1,301 @@ -+/* GStreamer Decoder Transform -+ * -+ * Copyright 2021 Derek Lesho -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+#include "gst_private.h" -+ -+#include "mfapi.h" -+#include "mferror.h" -+#include "mfobjects.h" -+#include "mftransform.h" -+ -+#include "wine/debug.h" -+#include "wine/heap.h" -+ -+WINE_DEFAULT_DEBUG_CHANNEL(mfplat); -+ -+struct mf_decoder -+{ -+ IMFTransform IMFTransform_iface; -+ LONG refcount; -+}; -+ -+static struct mf_decoder *impl_mf_decoder_from_IMFTransform(IMFTransform *iface) -+{ -+ return CONTAINING_RECORD(iface, struct mf_decoder, IMFTransform_iface); -+} -+ -+static HRESULT WINAPI mf_decoder_QueryInterface (IMFTransform *iface, REFIID riid, void **out) -+{ -+ TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out); -+ -+ if (IsEqualIID(riid, &IID_IMFTransform) || -+ IsEqualIID(riid, &IID_IUnknown)) -+ { -+ *out = iface; -+ IMFTransform_AddRef(iface); -+ return S_OK; -+ } -+ -+ WARN("Unsupported %s.\n", debugstr_guid(riid)); -+ *out = NULL; -+ return E_NOINTERFACE; -+} -+ -+static ULONG WINAPI mf_decoder_AddRef(IMFTransform *iface) -+{ -+ struct mf_decoder *decoder = impl_mf_decoder_from_IMFTransform(iface); -+ ULONG refcount = InterlockedIncrement(&decoder->refcount); -+ -+ TRACE("%p, refcount %u.\n", iface, refcount); -+ -+ return refcount; -+} -+ -+static ULONG WINAPI mf_decoder_Release(IMFTransform *iface) -+{ -+ struct mf_decoder *decoder = impl_mf_decoder_from_IMFTransform(iface); -+ ULONG refcount = InterlockedDecrement(&decoder->refcount); -+ -+ TRACE("%p, refcount %u.\n", iface, refcount); -+ -+ if (!refcount) -+ { -+ heap_free(decoder); -+ } -+ -+ return refcount; -+} -+ -+static HRESULT WINAPI mf_decoder_GetStreamLimits(IMFTransform *iface, DWORD *input_minimum, DWORD *input_maximum, -+ DWORD *output_minimum, DWORD *output_maximum) -+{ -+ TRACE("%p, %p, %p, %p, %p.\n", iface, input_minimum, input_maximum, output_minimum, output_maximum); -+ -+ *input_minimum = *input_maximum = *output_minimum = *output_maximum = 1; -+ -+ return S_OK; -+} -+ -+static HRESULT WINAPI mf_decoder_GetStreamCount(IMFTransform *iface, DWORD *inputs, DWORD *outputs) -+{ -+ TRACE("%p %p %p.\n", iface, inputs, outputs); -+ -+ *inputs = *outputs = 1; -+ -+ return S_OK; -+} -+ -+static HRESULT WINAPI mf_decoder_GetStreamIDs(IMFTransform *iface, DWORD input_size, DWORD *inputs, -+ DWORD output_size, DWORD *outputs) -+{ -+ TRACE("%p %u %p %u %p.\n", iface, input_size, inputs, output_size, outputs); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI mf_decoder_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info) -+{ -+ FIXME("%p %u %p.\n", iface, id, info); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI mf_decoder_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info) -+{ -+ FIXME("%p %u %p.\n", iface, id, info); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI mf_decoder_GetAttributes(IMFTransform *iface, IMFAttributes **attributes) -+{ -+ FIXME("%p, %p.\n", iface, attributes); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI mf_decoder_GetInputStreamAttributes(IMFTransform *iface, DWORD id, -+ IMFAttributes **attributes) -+{ -+ FIXME("%p, %u, %p.\n", iface, id, attributes); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI mf_decoder_GetOutputStreamAttributes(IMFTransform *iface, DWORD id, -+ IMFAttributes **attributes) -+{ -+ FIXME("%p, %u, %p.\n", iface, id, attributes); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI mf_decoder_DeleteInputStream(IMFTransform *iface, DWORD id) -+{ -+ TRACE("%p, %u.\n", iface, id); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI mf_decoder_AddInputStreams(IMFTransform *iface, DWORD streams, DWORD *ids) -+{ -+ TRACE("%p, %u, %p.\n", iface, streams, ids); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI mf_decoder_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index, -+ IMFMediaType **type) -+{ -+ FIXME("%p, %u, %u, %p.\n", iface, id, index, type); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI mf_decoder_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index, -+ IMFMediaType **type) -+{ -+ FIXME("%p, %u, %u, %p.\n", iface, id, index, type); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI mf_decoder_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) -+{ -+ FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI mf_decoder_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) -+{ -+ FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI mf_decoder_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) -+{ -+ FIXME("%p, %u, %p.\n", iface, id, type); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI mf_decoder_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) -+{ -+ FIXME("%p, %u, %p.\n", iface, id, type); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI mf_decoder_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags) -+{ -+ FIXME("%p, %u, %p\n", iface, id, flags); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI mf_decoder_GetOutputStatus(IMFTransform *iface, DWORD *flags) -+{ -+ FIXME("%p, %p.\n", iface, flags); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI mf_decoder_SetOutputBounds(IMFTransform *iface, LONGLONG lower, LONGLONG upper) -+{ -+ FIXME("%p, %s, %s.\n", iface, wine_dbgstr_longlong(lower), wine_dbgstr_longlong(upper)); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI mf_decoder_ProcessEvent(IMFTransform *iface, DWORD id, IMFMediaEvent *event) -+{ -+ FIXME("%p, %u, %p.\n", iface, id, event); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI mf_decoder_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param) -+{ -+ FIXME("%p, %u %lu.\n", iface, message, param); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI mf_decoder_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags) -+{ -+ FIXME("%p, %u, %p, %#x.\n", iface, id, sample, flags); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI mf_decoder_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count, -+ MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status) -+{ -+ FIXME("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status); -+ -+ return E_NOTIMPL; -+} -+ -+static const IMFTransformVtbl mf_decoder_vtbl = -+{ -+ mf_decoder_QueryInterface, -+ mf_decoder_AddRef, -+ mf_decoder_Release, -+ mf_decoder_GetStreamLimits, -+ mf_decoder_GetStreamCount, -+ mf_decoder_GetStreamIDs, -+ mf_decoder_GetInputStreamInfo, -+ mf_decoder_GetOutputStreamInfo, -+ mf_decoder_GetAttributes, -+ mf_decoder_GetInputStreamAttributes, -+ mf_decoder_GetOutputStreamAttributes, -+ mf_decoder_DeleteInputStream, -+ mf_decoder_AddInputStreams, -+ mf_decoder_GetInputAvailableType, -+ mf_decoder_GetOutputAvailableType, -+ mf_decoder_SetInputType, -+ mf_decoder_SetOutputType, -+ mf_decoder_GetInputCurrentType, -+ mf_decoder_GetOutputCurrentType, -+ mf_decoder_GetInputStatus, -+ mf_decoder_GetOutputStatus, -+ mf_decoder_SetOutputBounds, -+ mf_decoder_ProcessEvent, -+ mf_decoder_ProcessMessage, -+ mf_decoder_ProcessInput, -+ mf_decoder_ProcessOutput, -+}; -+ -+HRESULT decode_transform_create(REFIID riid, void **obj) -+{ -+ struct mf_decoder *object; -+ -+ TRACE("%s, %p.\n", debugstr_guid(riid), obj); -+ -+ if (!(object = heap_alloc_zero(sizeof(*object)))) -+ return E_OUTOFMEMORY; -+ -+ object->IMFTransform_iface.lpVtbl = &mf_decoder_vtbl; -+ object->refcount = 1; -+ -+ *obj = &object->IMFTransform_iface; -+ return S_OK; -+} -diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h -index 3584f465218..588aa50bccd 100644 ---- a/dlls/winegstreamer/gst_private.h -+++ b/dlls/winegstreamer/gst_private.h -@@ -119,6 +119,8 @@ HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj); - - HRESULT audio_converter_create(REFIID riid, void **ret); - -+HRESULT decode_transform_create(REFIID riid, void **obj) DECLSPEC_HIDDEN; -+ - struct wm_stream - { - struct wm_reader *reader; -diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c -index 51a71d3b4a5..8f487655748 100644 ---- a/dlls/winegstreamer/main.c -+++ b/dlls/winegstreamer/main.c -@@ -547,6 +547,9 @@ HRESULT WINAPI DllRegisterServer(void) - - init_gstreamer(); - -+ if (FAILED(hr = mfplat_DllRegisterServer())) -+ return hr; -+ - if (FAILED(hr = __wine_register_resources())) - return hr; - -diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index a111bbe196d..8b455a67aa2 100644 ---- a/dlls/winegstreamer/mfplat.c -+++ b/dlls/winegstreamer/mfplat.c -@@ -408,6 +408,7 @@ class_objects[] = - { &CLSID_VideoProcessorMFT, &video_processor_create }, - { &CLSID_GStreamerByteStreamHandler, &winegstreamer_stream_handler_create }, - { &CLSID_WINEAudioConverter, &audio_converter_create }, -+ { &CLSID_MSH264DecoderMFT, &decode_transform_create }, - }; - - HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) -diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl -index 90dc1dc839b..022f5f80980 100644 ---- a/dlls/winegstreamer/winegstreamer_classes.idl -+++ b/dlls/winegstreamer/winegstreamer_classes.idl -@@ -73,3 +73,9 @@ coclass WINEAudioConverter { } - uuid(2eeb4adf-4578-4d10-bca7-bb955f56320a) - ] - coclass CWMADecMediaObject {}; -+ -+[ -+ threading(both), -+ uuid(62ce7e72-4c71-4d20-b15d-452831a87d9d) -+] -+coclass CMSH264DecoderMFT { } --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0016-winegstreamer-Implement-GetInputAvailableType-for-de.patch b/patches/mfplat-streaming-support/0016-winegstreamer-Implement-GetInputAvailableType-for-de.patch deleted file mode 100644 index ece3beb8..00000000 --- a/patches/mfplat-streaming-support/0016-winegstreamer-Implement-GetInputAvailableType-for-de.patch +++ /dev/null @@ -1,158 +0,0 @@ -From 26157534099bf6653456d66d964c5c2f09f9a9a7 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Tue, 14 Dec 2021 13:36:27 +0100 -Subject: [PATCH 16/88] winegstreamer: Implement ::GetInputAvailableType for - decode transform. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/decode_transform.c | 60 +++++++++++++++++++++++++-- - dlls/winegstreamer/gst_private.h | 6 ++- - dlls/winegstreamer/mfplat.c | 7 +++- - 3 files changed, 67 insertions(+), 6 deletions(-) - -diff --git a/dlls/winegstreamer/decode_transform.c b/dlls/winegstreamer/decode_transform.c -index f5d4763bde4..55a0c1c6c9b 100644 ---- a/dlls/winegstreamer/decode_transform.c -+++ b/dlls/winegstreamer/decode_transform.c -@@ -29,10 +29,33 @@ - - WINE_DEFAULT_DEBUG_CHANNEL(mfplat); - -+const GUID *h264_input_types[] = {&MFVideoFormat_H264}; -+/* NV12 comes first https://docs.microsoft.com/en-us/windows/win32/medfound/mft-decoder-expose-output-types-in-native-order . thanks to @vitorhnn */ -+const GUID *h264_output_types[] = {&MFVideoFormat_NV12, &MFVideoFormat_I420, &MFVideoFormat_IYUV, &MFVideoFormat_YUY2, &MFVideoFormat_YV12}; -+ -+static struct decoder_desc -+{ -+ const GUID *major_type; -+ const GUID **input_types; -+ unsigned int input_types_count; -+ const GUID **output_types; -+ unsigned int output_types_count; -+} decoder_descs[] = -+{ -+ { /* DECODER_TYPE_H264 */ -+ &MFMediaType_Video, -+ h264_input_types, -+ ARRAY_SIZE(h264_input_types), -+ h264_output_types, -+ ARRAY_SIZE(h264_output_types), -+ }, -+}; -+ - struct mf_decoder - { - IMFTransform IMFTransform_iface; - LONG refcount; -+ enum decoder_type type; - }; - - static struct mf_decoder *impl_mf_decoder_from_IMFTransform(IMFTransform *iface) -@@ -163,9 +186,36 @@ static HRESULT WINAPI mf_decoder_AddInputStreams(IMFTransform *iface, DWORD stre - static HRESULT WINAPI mf_decoder_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index, - IMFMediaType **type) - { -- FIXME("%p, %u, %u, %p.\n", iface, id, index, type); -+ struct mf_decoder *decoder = impl_mf_decoder_from_IMFTransform(iface); -+ IMFMediaType *input_type; -+ HRESULT hr; - -- return E_NOTIMPL; -+ TRACE("%p, %u, %u, %p\n", decoder, id, index, type); -+ -+ if (id != 0) -+ return MF_E_INVALIDSTREAMNUMBER; -+ -+ if (index >= decoder_descs[decoder->type].input_types_count) -+ return MF_E_NO_MORE_TYPES; -+ -+ if (FAILED(hr = MFCreateMediaType(&input_type))) -+ return hr; -+ -+ if (FAILED(hr = IMFMediaType_SetGUID(input_type, &MF_MT_MAJOR_TYPE, decoder_descs[decoder->type].major_type))) -+ { -+ IMFMediaType_Release(input_type); -+ return hr; -+ } -+ -+ if (FAILED(hr = IMFMediaType_SetGUID(input_type, &MF_MT_SUBTYPE, decoder_descs[decoder->type].input_types[index]))) -+ { -+ IMFMediaType_Release(input_type); -+ return hr; -+ } -+ -+ *type = input_type; -+ -+ return S_OK; - } - - static HRESULT WINAPI mf_decoder_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index, -@@ -284,11 +334,11 @@ static const IMFTransformVtbl mf_decoder_vtbl = - mf_decoder_ProcessOutput, - }; - --HRESULT decode_transform_create(REFIID riid, void **obj) -+HRESULT decode_transform_create(REFIID riid, void **obj, enum decoder_type type) - { - struct mf_decoder *object; - -- TRACE("%s, %p.\n", debugstr_guid(riid), obj); -+ TRACE("%s, %p %u.\n", debugstr_guid(riid), obj, type); - - if (!(object = heap_alloc_zero(sizeof(*object)))) - return E_OUTOFMEMORY; -@@ -296,6 +346,8 @@ HRESULT decode_transform_create(REFIID riid, void **obj) - object->IMFTransform_iface.lpVtbl = &mf_decoder_vtbl; - object->refcount = 1; - -+ object->type = type; -+ - *obj = &object->IMFTransform_iface; - return S_OK; - } -diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h -index 588aa50bccd..b9379487ac2 100644 ---- a/dlls/winegstreamer/gst_private.h -+++ b/dlls/winegstreamer/gst_private.h -@@ -119,7 +119,11 @@ HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj); - - HRESULT audio_converter_create(REFIID riid, void **ret); - --HRESULT decode_transform_create(REFIID riid, void **obj) DECLSPEC_HIDDEN; -+enum decoder_type -+{ -+ DECODER_TYPE_H264, -+}; -+HRESULT decode_transform_create(REFIID riid, void **obj, enum decoder_type) DECLSPEC_HIDDEN; - - struct wm_stream - { -diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index 8b455a67aa2..93ddb90a070 100644 ---- a/dlls/winegstreamer/mfplat.c -+++ b/dlls/winegstreamer/mfplat.c -@@ -398,6 +398,11 @@ static const GUID CLSID_GStreamerByteStreamHandler = {0x317df618, 0x5e5a, 0x468a - - static const GUID CLSID_WINEAudioConverter = {0x6a170414,0xaad9,0x4693,{0xb8,0x06,0x3a,0x0c,0x47,0xc5,0x70,0xd6}}; - -+static HRESULT h264_decoder_create(REFIID riid, void **ret) -+{ -+ return decode_transform_create(riid, ret, DECODER_TYPE_H264); -+} -+ - static const struct class_object - { - const GUID *clsid; -@@ -408,7 +413,7 @@ class_objects[] = - { &CLSID_VideoProcessorMFT, &video_processor_create }, - { &CLSID_GStreamerByteStreamHandler, &winegstreamer_stream_handler_create }, - { &CLSID_WINEAudioConverter, &audio_converter_create }, -- { &CLSID_MSH264DecoderMFT, &decode_transform_create }, -+ { &CLSID_MSH264DecoderMFT, &h264_decoder_create }, - }; - - HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0017-winegstreamer-Implement-GetOutputAvailableType-for-d.patch b/patches/mfplat-streaming-support/0017-winegstreamer-Implement-GetOutputAvailableType-for-d.patch deleted file mode 100644 index 0b09a3cf..00000000 --- a/patches/mfplat-streaming-support/0017-winegstreamer-Implement-GetOutputAvailableType-for-d.patch +++ /dev/null @@ -1,57 +0,0 @@ -From bfa940843cf60483a21e9dc135328d19f839f13a Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Wed, 10 Mar 2021 14:23:09 -0500 -Subject: [PATCH 17/88] winegstreamer: Implement ::GetOutputAvailableType for - decode transform. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/decode_transform.c | 31 +++++++++++++++++++++++++-- - 1 file changed, 29 insertions(+), 2 deletions(-) - -diff --git a/dlls/winegstreamer/decode_transform.c b/dlls/winegstreamer/decode_transform.c -index 55a0c1c6c9b..3c71fddd67c 100644 ---- a/dlls/winegstreamer/decode_transform.c -+++ b/dlls/winegstreamer/decode_transform.c -@@ -221,9 +221,36 @@ static HRESULT WINAPI mf_decoder_GetInputAvailableType(IMFTransform *iface, DWOR - static HRESULT WINAPI mf_decoder_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index, - IMFMediaType **type) - { -- FIXME("%p, %u, %u, %p.\n", iface, id, index, type); -+ struct mf_decoder *decoder = impl_mf_decoder_from_IMFTransform(iface); -+ IMFMediaType *output_type; -+ HRESULT hr; - -- return E_NOTIMPL; -+ TRACE("%p, %u, %u, %p\n", decoder, id, index, type); -+ -+ if (id != 0) -+ return MF_E_INVALIDSTREAMNUMBER; -+ -+ if (index >= decoder_descs[decoder->type].output_types_count) -+ return MF_E_NO_MORE_TYPES; -+ -+ if (FAILED(hr = MFCreateMediaType(&output_type))) -+ return hr; -+ -+ if (FAILED(hr = IMFMediaType_SetGUID(output_type, &MF_MT_MAJOR_TYPE, decoder_descs[decoder->type].major_type))) -+ { -+ IMFMediaType_Release(output_type); -+ return hr; -+ } -+ -+ if (FAILED(hr = IMFMediaType_SetGUID(output_type, &MF_MT_SUBTYPE, decoder_descs[decoder->type].output_types[index]))) -+ { -+ IMFMediaType_Release(output_type); -+ return hr; -+ } -+ -+ *type = output_type; -+ -+ return S_OK; - } - - static HRESULT WINAPI mf_decoder_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0018-winegstreamer-Implement-SetInputType-for-decode-tran.patch b/patches/mfplat-streaming-support/0018-winegstreamer-Implement-SetInputType-for-decode-tran.patch deleted file mode 100644 index 42c41d0b..00000000 --- a/patches/mfplat-streaming-support/0018-winegstreamer-Implement-SetInputType-for-decode-tran.patch +++ /dev/null @@ -1,305 +0,0 @@ -From 29aad7626e6a5bcdabdacb579ff3e9b707ed8452 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Thu, 11 Mar 2021 12:33:02 -0500 -Subject: [PATCH 18/88] winegstreamer: Implement ::SetInputType for decode - transform. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/decode_transform.c | 80 ++++++++++++++++++++++++++- - dlls/winegstreamer/mfplat.c | 17 +++++- - dlls/winegstreamer/quartz_parser.c | 1 + - dlls/winegstreamer/unixlib.h | 10 ++++ - dlls/winegstreamer/wg_parser.c | 76 +++++++++++++++++++++++++ - 5 files changed, 180 insertions(+), 4 deletions(-) - -diff --git a/dlls/winegstreamer/decode_transform.c b/dlls/winegstreamer/decode_transform.c -index 3c71fddd67c..f709ef32fc1 100644 ---- a/dlls/winegstreamer/decode_transform.c -+++ b/dlls/winegstreamer/decode_transform.c -@@ -56,6 +56,8 @@ struct mf_decoder - IMFTransform IMFTransform_iface; - LONG refcount; - enum decoder_type type; -+ IMFMediaType *input_type; -+ CRITICAL_SECTION cs; - }; - - static struct mf_decoder *impl_mf_decoder_from_IMFTransform(IMFTransform *iface) -@@ -99,6 +101,14 @@ static ULONG WINAPI mf_decoder_Release(IMFTransform *iface) - - if (!refcount) - { -+ if (decoder->input_type) -+ { -+ IMFMediaType_Release(decoder->input_type); -+ decoder->input_type = NULL; -+ } -+ -+ DeleteCriticalSection(&decoder->cs); -+ - heap_free(decoder); - } - -@@ -255,9 +265,73 @@ static HRESULT WINAPI mf_decoder_GetOutputAvailableType(IMFTransform *iface, DWO - - static HRESULT WINAPI mf_decoder_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) - { -- FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags); -+ struct mf_decoder *decoder = impl_mf_decoder_from_IMFTransform(iface); -+ struct wg_format input_format; -+ GUID major_type, subtype; -+ unsigned int i; -+ HRESULT hr; - -- return E_NOTIMPL; -+ TRACE("%p, %u, %p, %#x.\n", decoder, id, type, flags); -+ -+ if (id != 0) -+ return MF_E_INVALIDSTREAMNUMBER; -+ -+ if (!type) -+ { -+ if (flags & MFT_SET_TYPE_TEST_ONLY) -+ return S_OK; -+ -+ EnterCriticalSection(&decoder->cs); -+ -+ if (decoder->input_type) -+ { -+ IMFMediaType_Release(decoder->input_type); -+ decoder->input_type = NULL; -+ } -+ -+ LeaveCriticalSection(&decoder->cs); -+ -+ return S_OK; -+ } -+ -+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type))) -+ return MF_E_INVALIDTYPE; -+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype))) -+ return MF_E_INVALIDTYPE; -+ -+ if (!(IsEqualGUID(&major_type, decoder_descs[decoder->type].major_type))) -+ return MF_E_INVALIDTYPE; -+ -+ for (i = 0; i < decoder_descs[decoder->type].input_types_count; i++) -+ { -+ if (IsEqualGUID(&subtype, decoder_descs[decoder->type].input_types[i])) -+ break; -+ if (i == decoder_descs[decoder->type].input_types_count) -+ return MF_E_INVALIDTYPE; -+ } -+ -+ mf_media_type_to_wg_format(type, &input_format); -+ if (!input_format.major_type) -+ return MF_E_INVALIDTYPE; -+ -+ if (flags & MFT_SET_TYPE_TEST_ONLY) -+ return S_OK; -+ -+ EnterCriticalSection(&decoder->cs); -+ -+ hr = S_OK; -+ -+ if (!decoder->input_type) -+ hr = MFCreateMediaType(&decoder->input_type); -+ -+ if (SUCCEEDED(hr) && FAILED(hr = IMFMediaType_CopyAllItems(type, (IMFAttributes*) decoder->input_type))) -+ { -+ IMFMediaType_Release(decoder->input_type); -+ decoder->input_type = NULL; -+ } -+ -+ LeaveCriticalSection(&decoder->cs); -+ return hr; - } - - static HRESULT WINAPI mf_decoder_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) -@@ -375,6 +449,8 @@ HRESULT decode_transform_create(REFIID riid, void **obj, enum decoder_type type) - - object->type = type; - -+ InitializeCriticalSection(&object->cs); -+ - *obj = &object->IMFTransform_iface; - return S_OK; - } -diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index 93ddb90a070..4fe11b7b6b8 100644 ---- a/dlls/winegstreamer/mfplat.c -+++ b/dlls/winegstreamer/mfplat.c -@@ -554,6 +554,7 @@ video_formats[] = - {&MFVideoFormat_YUY2, WG_VIDEO_FORMAT_YUY2}, - {&MFVideoFormat_YV12, WG_VIDEO_FORMAT_YV12}, - {&MFVideoFormat_YVYU, WG_VIDEO_FORMAT_YVYU}, -+ {&MFVideoFormat_H264, WG_VIDEO_FORMAT_H264}, - }; - - static const struct -@@ -741,10 +742,22 @@ static void mf_media_type_to_wg_format_video(IMFMediaType *type, struct wg_forma - if (IsEqualGUID(&subtype, video_formats[i].subtype)) - { - format->u.video.format = video_formats[i].format; -- return; -+ break; - } - } -- FIXME("Unrecognized video subtype %s.\n", debugstr_guid(&subtype)); -+ if (i == ARRAY_SIZE(video_formats)) -+ FIXME("Unrecognized video subtype %s.\n", debugstr_guid(&subtype)); -+ -+ if (format->u.video.format == WG_VIDEO_FORMAT_H264) -+ { -+ UINT32 profile, level; -+ -+ if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_MPEG2_PROFILE, &profile))) -+ format->u.video.compressed.h264.profile = profile; -+ -+ if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_MPEG2_LEVEL, &level))) -+ format->u.video.compressed.h264.level = level; -+ } - } - - void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format) -diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c -index 45313ebda27..0328b5ed4f5 100644 ---- a/dlls/winegstreamer/quartz_parser.c -+++ b/dlls/winegstreamer/quartz_parser.c -@@ -271,6 +271,7 @@ unsigned int wg_format_get_max_size(const struct wg_format *format) - * but as long as every sample fits into our allocator, we're fine. */ - return width * height * 3; - -+ case WG_VIDEO_FORMAT_H264: - case WG_VIDEO_FORMAT_UNKNOWN: - FIXME("Cannot guess maximum sample size for unknown video format.\n"); - return 0; -diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h -index 82bb534b938..f3db631d16d 100644 ---- a/dlls/winegstreamer/unixlib.h -+++ b/dlls/winegstreamer/unixlib.h -@@ -62,9 +62,19 @@ struct wg_format - WG_VIDEO_FORMAT_YVYU, - - WG_VIDEO_FORMAT_CINEPAK, -+ -+ WG_VIDEO_FORMAT_H264, - } format; - int32_t width, height; - uint32_t fps_n, fps_d; -+ union -+ { -+ struct -+ { -+ uint32_t profile; -+ uint32_t level; -+ } h264; -+ } compressed; - } video; - struct - { -diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index c6e8bbcb26b..c2141fae2af 100644 ---- a/dlls/winegstreamer/wg_parser.c -+++ b/dlls/winegstreamer/wg_parser.c -@@ -406,6 +406,22 @@ static void wg_channel_mask_to_gst(GstAudioChannelPosition *positions, uint32_t - } - } - -+static void wg_set_caps_from_wg_format(GstCaps *caps, const struct wg_format *format) -+{ -+ switch (format->major_type) -+ { -+ case WG_MAJOR_TYPE_VIDEO: -+ { -+ gst_caps_set_simple(caps, "width", G_TYPE_INT, format->u.video.width, NULL); -+ gst_caps_set_simple(caps, "height", G_TYPE_INT, format->u.video.height, NULL); -+ gst_caps_set_simple(caps, "framerate", GST_TYPE_FRACTION, format->u.video.fps_n, format->u.video.fps_d, NULL); -+ break; -+ } -+ default: -+ break; -+ } -+} -+ - static GstCaps *wg_format_to_caps_audio(const struct wg_format *format) - { - GstAudioChannelPosition positions[32]; -@@ -447,6 +463,65 @@ static GstCaps *wg_format_to_caps_video(const struct wg_format *format) - unsigned int i; - GstCaps *caps; - -+ /* compressed types */ -+ -+ if (format->u.video.format == WG_VIDEO_FORMAT_H264) -+ { -+ const char *profile; -+ const char *level; -+ -+ caps = gst_caps_new_empty_simple("video/x-h264"); -+ wg_set_caps_from_wg_format(caps, format); -+ -+ gst_caps_set_simple(caps, "stream-format", G_TYPE_STRING, "byte-stream", NULL); -+ gst_caps_set_simple(caps, "alignment", G_TYPE_STRING, "au", NULL); -+ -+ switch (format->u.video.compressed.h264.profile) -+ { -+ case /* eAVEncH264VProfile_Main */ 77: profile = "main"; break; -+ case /* eAVEncH264VProfile_High */ 100: profile = "high"; break; -+ case /* eAVEncH264VProfile_444 */ 244: profile = "high-4:4:4"; break; -+ default: -+ GST_ERROR("Unrecognized H.264 profile attribute %u\n", format->u.video.compressed.h264.profile); -+ /* fallthrough */ -+ case 0: profile = NULL; -+ } -+ -+ switch (format->u.video.compressed.h264.level) -+ { -+ case /* eAVEncH264VLevel1 */ 10: level = "1"; break; -+ case /* eAVEncH264VLevel1_1 */ 11: level = "1.1"; break; -+ case /* eAVEncH264VLevel1_2 */ 12: level = "1.2"; break; -+ case /* eAVEncH264VLevel1_3 */ 13: level = "1.3"; break; -+ case /* eAVEncH264VLevel2 */ 20: level = "2"; break; -+ case /* eAVEncH264VLevel2_1 */ 21: level = "2.1"; break; -+ case /* eAVEncH264VLevel2_2 */ 22: level = "2.2"; break; -+ case /* eAVEncH264VLevel3 */ 30: level = "3"; break; -+ case /* eAVEncH264VLevel3_1 */ 31: level = "3.1"; break; -+ case /* eAVEncH264VLevel3_2 */ 32: level = "3.2"; break; -+ case /* eAVEncH264VLevel4 */ 40: level = "4"; break; -+ case /* eAVEncH264VLevel4_1 */ 41: level = "4.1"; break; -+ case /* eAVEncH264VLevel4_2 */ 42: level = "4.2"; break; -+ case /* eAVEncH264VLevel5 */ 50: level = "5"; break; -+ case /* eAVEncH264VLevel5_1 */ 51: level = "5.1"; break; -+ case /* eAVEncH264VLevel5_2 */ 52: level = "5.2"; break; -+ default: -+ GST_ERROR("Unrecognized H.264 level attribute %u\n", format->u.video.compressed.h264.level); -+ /* fallthrough */ -+ case 0: level = NULL; -+ } -+ -+ if (profile) -+ gst_caps_set_simple(caps, "profile", G_TYPE_STRING, profile, NULL); -+ -+ if (level) -+ gst_caps_set_simple(caps, "level", G_TYPE_STRING, level, NULL); -+ -+ return caps; -+ } -+ -+ /* uncompressed types */ -+ - if ((video_format = wg_video_format_to_gst(format->u.video.format)) == GST_VIDEO_FORMAT_UNKNOWN) - return NULL; - -@@ -655,6 +730,7 @@ static NTSTATUS wg_parser_stream_enable(void *args) - case WG_VIDEO_FORMAT_YVYU: - case WG_VIDEO_FORMAT_UNKNOWN: - case WG_VIDEO_FORMAT_CINEPAK: -+ case WG_VIDEO_FORMAT_H264: - break; - } - --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0019-winegstreamer-Implement-SetOutputType-for-decode-tra.patch b/patches/mfplat-streaming-support/0019-winegstreamer-Implement-SetOutputType-for-decode-tra.patch deleted file mode 100644 index 6d94efbe..00000000 --- a/patches/mfplat-streaming-support/0019-winegstreamer-Implement-SetOutputType-for-decode-tra.patch +++ /dev/null @@ -1,116 +0,0 @@ -From 760c4df96ca2e4deb5c7c7e26fb81713a9393e5e Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Thu, 11 Mar 2021 12:58:32 -0500 -Subject: [PATCH 19/88] winegstreamer: Implement ::SetOutputType for decode - transform. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/decode_transform.c | 76 +++++++++++++++++++++++++-- - 1 file changed, 73 insertions(+), 3 deletions(-) - -diff --git a/dlls/winegstreamer/decode_transform.c b/dlls/winegstreamer/decode_transform.c -index f709ef32fc1..0848cb47c9d 100644 ---- a/dlls/winegstreamer/decode_transform.c -+++ b/dlls/winegstreamer/decode_transform.c -@@ -56,7 +56,7 @@ struct mf_decoder - IMFTransform IMFTransform_iface; - LONG refcount; - enum decoder_type type; -- IMFMediaType *input_type; -+ IMFMediaType *input_type, *output_type; - CRITICAL_SECTION cs; - }; - -@@ -107,6 +107,12 @@ static ULONG WINAPI mf_decoder_Release(IMFTransform *iface) - decoder->input_type = NULL; - } - -+ if (decoder->output_type) -+ { -+ IMFMediaType_Release(decoder->output_type); -+ decoder->output_type = NULL; -+ } -+ - DeleteCriticalSection(&decoder->cs); - - heap_free(decoder); -@@ -336,9 +342,73 @@ static HRESULT WINAPI mf_decoder_SetInputType(IMFTransform *iface, DWORD id, IMF - - static HRESULT WINAPI mf_decoder_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) - { -- FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags); -+ struct mf_decoder *decoder = impl_mf_decoder_from_IMFTransform(iface); -+ struct wg_format output_format; -+ GUID major_type, subtype; -+ HRESULT hr; -+ unsigned int i; - -- return E_NOTIMPL; -+ TRACE("%p, %u, %p, %#x.\n", decoder, id, type, flags); -+ -+ if (id != 0) -+ return MF_E_INVALIDSTREAMNUMBER; -+ -+ if (!type) -+ { -+ if (flags & MFT_SET_TYPE_TEST_ONLY) -+ return S_OK; -+ -+ EnterCriticalSection(&decoder->cs); -+ -+ if (decoder->output_type) -+ { -+ IMFMediaType_Release(decoder->output_type); -+ decoder->output_type = NULL; -+ } -+ -+ LeaveCriticalSection(&decoder->cs); -+ -+ return S_OK; -+ } -+ -+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type))) -+ return MF_E_INVALIDTYPE; -+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype))) -+ return MF_E_INVALIDTYPE; -+ -+ if (!(IsEqualGUID(&major_type, decoder_descs[decoder->type].major_type))) -+ return MF_E_INVALIDTYPE; -+ -+ for (i = 0; i < decoder_descs[decoder->type].output_types_count; i++) -+ { -+ if (IsEqualGUID(&subtype, decoder_descs[decoder->type].output_types[i])) -+ break; -+ if (i == decoder_descs[decoder->type].output_types_count) -+ return MF_E_INVALIDTYPE; -+ } -+ -+ mf_media_type_to_wg_format(type, &output_format); -+ if (!output_format.major_type) -+ return MF_E_INVALIDTYPE; -+ -+ if (flags & MFT_SET_TYPE_TEST_ONLY) -+ return S_OK; -+ -+ EnterCriticalSection(&decoder->cs); -+ -+ hr = S_OK; -+ -+ if (!decoder->output_type) -+ hr = MFCreateMediaType(&decoder->output_type); -+ -+ if (SUCCEEDED(hr) && FAILED(hr = IMFMediaType_CopyAllItems(type, (IMFAttributes*) decoder->output_type))) -+ { -+ IMFMediaType_Release(decoder->output_type); -+ decoder->output_type = NULL; -+ } -+ -+ LeaveCriticalSection(&decoder->cs); -+ return hr; - } - - static HRESULT WINAPI mf_decoder_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0020-winegstreamer-Implement-Get-Input-Output-StreamInfo-.patch b/patches/mfplat-streaming-support/0020-winegstreamer-Implement-Get-Input-Output-StreamInfo-.patch deleted file mode 100644 index d60f6047..00000000 --- a/patches/mfplat-streaming-support/0020-winegstreamer-Implement-Get-Input-Output-StreamInfo-.patch +++ /dev/null @@ -1,106 +0,0 @@ -From 372d42fdb36cef1e845eb8ac9d461d5f03974605 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Thu, 11 Mar 2021 14:40:32 -0500 -Subject: [PATCH 20/88] winegstreamer: Implement ::Get(Input/Output)StreamInfo - for decode transform. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/decode_transform.c | 61 +++++++++++++++++++++++++-- - 1 file changed, 57 insertions(+), 4 deletions(-) - -diff --git a/dlls/winegstreamer/decode_transform.c b/dlls/winegstreamer/decode_transform.c -index 0848cb47c9d..dadd161bcc9 100644 ---- a/dlls/winegstreamer/decode_transform.c -+++ b/dlls/winegstreamer/decode_transform.c -@@ -58,6 +58,7 @@ struct mf_decoder - enum decoder_type type; - IMFMediaType *input_type, *output_type; - CRITICAL_SECTION cs; -+ BOOL video; - }; - - static struct mf_decoder *impl_mf_decoder_from_IMFTransform(IMFTransform *iface) -@@ -150,16 +151,67 @@ static HRESULT WINAPI mf_decoder_GetStreamIDs(IMFTransform *iface, DWORD input_s - - static HRESULT WINAPI mf_decoder_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info) - { -- FIXME("%p %u %p.\n", iface, id, info); -+ struct mf_decoder *decoder = impl_mf_decoder_from_IMFTransform(iface); - -- return E_NOTIMPL; -+ TRACE("%p %u %p\n", decoder, id, info); -+ -+ if (id != 0) -+ return MF_E_INVALIDSTREAMNUMBER; -+ -+ info->dwFlags = MFT_INPUT_STREAM_WHOLE_SAMPLES | MFT_INPUT_STREAM_DOES_NOT_ADDREF; -+ info->cbAlignment = 0; -+ info->cbSize = 0; -+ /* TODO: retrieve following fields from gstreamer */ -+ info->hnsMaxLatency = 0; -+ info->cbMaxLookahead = 0; -+ return S_OK; - } - - static HRESULT WINAPI mf_decoder_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info) - { -- FIXME("%p %u %p.\n", iface, id, info); -+ struct mf_decoder *decoder = impl_mf_decoder_from_IMFTransform(iface); -+ MFT_OUTPUT_STREAM_INFO stream_info = {}; -+ GUID output_subtype; -+ UINT64 framesize; - -- return E_NOTIMPL; -+ TRACE("%p %u %p\n", decoder, id, info); -+ -+ if (id != 0) -+ return MF_E_INVALIDSTREAMNUMBER; -+ -+ EnterCriticalSection(&decoder->cs); -+ -+ if (!decoder->output_type) -+ { -+ LeaveCriticalSection(&decoder->cs); -+ return MF_E_TRANSFORM_TYPE_NOT_SET; -+ } -+ -+ if (decoder->video) -+ { -+ stream_info.dwFlags = MFT_OUTPUT_STREAM_WHOLE_SAMPLES | MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER | -+ MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE | MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES; -+ stream_info.cbSize = 0; -+ if (SUCCEEDED(IMFMediaType_GetGUID(decoder->output_type, &MF_MT_SUBTYPE, &output_subtype)) && -+ SUCCEEDED(IMFMediaType_GetUINT64(decoder->output_type, &MF_MT_FRAME_SIZE, &framesize))) -+ { -+ MFCalculateImageSize(&output_subtype, framesize >> 32, (UINT32) framesize, &stream_info.cbSize); -+ } -+ if (!stream_info.cbSize) -+ ERR("Failed to get desired output buffer size\n"); -+ } -+ else -+ { -+ stream_info.dwFlags = MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE | MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES; -+ stream_info.cbSize = 4; -+ } -+ stream_info.cbAlignment = 0; -+ -+ LeaveCriticalSection(&decoder->cs); -+ -+ *info = stream_info; -+ -+ return S_OK; - } - - static HRESULT WINAPI mf_decoder_GetAttributes(IMFTransform *iface, IMFAttributes **attributes) -@@ -518,6 +570,7 @@ HRESULT decode_transform_create(REFIID riid, void **obj, enum decoder_type type) - object->refcount = 1; - - object->type = type; -+ object->video = decoder_descs[type].major_type == &MFMediaType_Video; - - InitializeCriticalSection(&object->cs); - --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0021-winegstreamer-Semi-stub-GetAttributes-for-decoder-tr.patch b/patches/mfplat-streaming-support/0021-winegstreamer-Semi-stub-GetAttributes-for-decoder-tr.patch deleted file mode 100644 index 4811a1cf..00000000 --- a/patches/mfplat-streaming-support/0021-winegstreamer-Semi-stub-GetAttributes-for-decoder-tr.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 95e4c7c7d5de17f6635f7028b364cacbdadb2e58 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Fri, 19 Mar 2021 16:55:15 -0400 -Subject: [PATCH 21/88] winegstreamer: Semi-stub ::GetAttributes for decoder - transform. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/decode_transform.c | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/dlls/winegstreamer/decode_transform.c b/dlls/winegstreamer/decode_transform.c -index dadd161bcc9..fb282d850ff 100644 ---- a/dlls/winegstreamer/decode_transform.c -+++ b/dlls/winegstreamer/decode_transform.c -@@ -216,9 +216,9 @@ static HRESULT WINAPI mf_decoder_GetOutputStreamInfo(IMFTransform *iface, DWORD - - static HRESULT WINAPI mf_decoder_GetAttributes(IMFTransform *iface, IMFAttributes **attributes) - { -- FIXME("%p, %p.\n", iface, attributes); -+ FIXME("%p, %p. semi-stub!\n", iface, attributes); - -- return E_NOTIMPL; -+ return MFCreateAttributes(attributes, 0); - } - - static HRESULT WINAPI mf_decoder_GetInputStreamAttributes(IMFTransform *iface, DWORD id, --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0022-winegstreamer-Register-the-H.264-decoder-transform.patch b/patches/mfplat-streaming-support/0022-winegstreamer-Register-the-H.264-decoder-transform.patch deleted file mode 100644 index fc1efb2c..00000000 --- a/patches/mfplat-streaming-support/0022-winegstreamer-Register-the-H.264-decoder-transform.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 8f392bb6b5de063a22fbb9ceb6e77a8f49bd7745 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Fri, 19 Mar 2021 16:57:11 -0400 -Subject: [PATCH 22/88] winegstreamer: Register the H.264 decoder transform. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/mfplat.c | 25 +++++++++++++++++++++++++ - 1 file changed, 25 insertions(+) - -diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index 4fe11b7b6b8..a4494822500 100644 ---- a/dlls/winegstreamer/mfplat.c -+++ b/dlls/winegstreamer/mfplat.c -@@ -463,6 +463,20 @@ static const GUID *const wma_decoder_output_types[] = - &MFAudioFormat_Float, - }; - -+static WCHAR h264_decoderW[] = L"H.264 Decoder"; -+static const GUID *h264_decoder_input_types[] = -+{ -+ &MFVideoFormat_H264, -+}; -+static const GUID *h264_decoder_output_types[] = -+{ -+ &MFVideoFormat_NV12, -+ &MFVideoFormat_I420, -+ &MFVideoFormat_IYUV, -+ &MFVideoFormat_YUY2, -+ &MFVideoFormat_YV12, -+}; -+ - static const struct mft - { - const GUID *clsid; -@@ -499,6 +513,17 @@ mfts[] = - ARRAY_SIZE(wma_decoder_output_types), - wma_decoder_output_types, - }, -+ { -+ &CLSID_MSH264DecoderMFT, -+ &MFT_CATEGORY_VIDEO_DECODER, -+ h264_decoderW, -+ MFT_ENUM_FLAG_SYNCMFT, -+ &MFMediaType_Video, -+ ARRAY_SIZE(h264_decoder_input_types), -+ h264_decoder_input_types, -+ ARRAY_SIZE(h264_decoder_output_types), -+ h264_decoder_output_types, -+ }, - }; - - HRESULT mfplat_DllRegisterServer(void) --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0023-winegstreamer-Introduce-AAC-decoder-transform.patch b/patches/mfplat-streaming-support/0023-winegstreamer-Introduce-AAC-decoder-transform.patch deleted file mode 100644 index 97d221a5..00000000 --- a/patches/mfplat-streaming-support/0023-winegstreamer-Introduce-AAC-decoder-transform.patch +++ /dev/null @@ -1,214 +0,0 @@ -From 8234bc8886ba39e341ff4c771ac41f5529d67088 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Fri, 19 Mar 2021 16:59:29 -0400 -Subject: [PATCH 23/88] winegstreamer: Introduce AAC decoder transform. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/decode_transform.c | 10 ++++ - dlls/winegstreamer/gst_private.h | 1 + - dlls/winegstreamer/mfplat.c | 58 +++++++++++++++++++- - dlls/winegstreamer/quartz_parser.c | 2 + - dlls/winegstreamer/unixlib.h | 16 ++++++ - dlls/winegstreamer/winegstreamer_classes.idl | 6 ++ - 6 files changed, 92 insertions(+), 1 deletion(-) - -diff --git a/dlls/winegstreamer/decode_transform.c b/dlls/winegstreamer/decode_transform.c -index fb282d850ff..4967fc49012 100644 ---- a/dlls/winegstreamer/decode_transform.c -+++ b/dlls/winegstreamer/decode_transform.c -@@ -33,6 +33,9 @@ const GUID *h264_input_types[] = {&MFVideoFormat_H264}; - /* NV12 comes first https://docs.microsoft.com/en-us/windows/win32/medfound/mft-decoder-expose-output-types-in-native-order . thanks to @vitorhnn */ - const GUID *h264_output_types[] = {&MFVideoFormat_NV12, &MFVideoFormat_I420, &MFVideoFormat_IYUV, &MFVideoFormat_YUY2, &MFVideoFormat_YV12}; - -+const GUID *aac_input_types[] = {&MFAudioFormat_AAC}; -+const GUID *aac_output_types[] = {&MFAudioFormat_Float}; -+ - static struct decoder_desc - { - const GUID *major_type; -@@ -49,6 +52,13 @@ static struct decoder_desc - h264_output_types, - ARRAY_SIZE(h264_output_types), - }, -+ { /* DECODER_TYPE_AAC */ -+ &MFMediaType_Audio, -+ aac_input_types, -+ ARRAY_SIZE(aac_input_types), -+ aac_output_types, -+ ARRAY_SIZE(aac_output_types), -+ } - }; - - struct mf_decoder -diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h -index b9379487ac2..73d5e88b164 100644 ---- a/dlls/winegstreamer/gst_private.h -+++ b/dlls/winegstreamer/gst_private.h -@@ -122,6 +122,7 @@ HRESULT audio_converter_create(REFIID riid, void **ret); - enum decoder_type - { - DECODER_TYPE_H264, -+ DECODER_TYPE_AAC, - }; - HRESULT decode_transform_create(REFIID riid, void **obj, enum decoder_type) DECLSPEC_HIDDEN; - -diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index a4494822500..e22cd51c8a9 100644 ---- a/dlls/winegstreamer/mfplat.c -+++ b/dlls/winegstreamer/mfplat.c -@@ -414,6 +414,7 @@ class_objects[] = - { &CLSID_GStreamerByteStreamHandler, &winegstreamer_stream_handler_create }, - { &CLSID_WINEAudioConverter, &audio_converter_create }, - { &CLSID_MSH264DecoderMFT, &h264_decoder_create }, -+ { &CLSID_MSAACDecMFT, &aac_decoder_create }, - }; - - HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) -@@ -620,7 +621,8 @@ static IMFMediaType *mf_media_type_from_wg_format_audio(const struct wg_format * - IMFMediaType_SetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, audio_formats[i].depth); - IMFMediaType_SetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, format->u.audio.rate); - IMFMediaType_SetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, format->u.audio.channels); -- IMFMediaType_SetUINT32(type, &MF_MT_AUDIO_CHANNEL_MASK, format->u.audio.channel_mask); -+ if (format->u.audio.channel_mask) -+ IMFMediaType_SetUINT32(type, &MF_MT_AUDIO_CHANNEL_MASK, format->u.audio.channel_mask); - IMFMediaType_SetUINT32(type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE); - IMFMediaType_SetUINT32(type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, format->u.audio.channels * audio_formats[i].depth / 8); - -@@ -710,6 +712,8 @@ static void mf_media_type_to_wg_format_audio(IMFMediaType *type, struct wg_forma - channel_mask = KSAUDIO_SPEAKER_MONO; - else if (channels == 2) - channel_mask = KSAUDIO_SPEAKER_STEREO; -+ else if IsEqualGUID(&subtype, &MFAudioFormat_AAC) -+ channel_mask = 0; - else - { - FIXME("Channel mask is not set.\n"); -@@ -722,6 +726,58 @@ static void mf_media_type_to_wg_format_audio(IMFMediaType *type, struct wg_forma - format->u.audio.channel_mask = channel_mask; - format->u.audio.rate = rate; - -+ if (IsEqualGUID(&subtype, &MFAudioFormat_AAC)) -+ { -+ UINT32 payload_type, indication, user_data_size; -+ unsigned char *user_data; -+ -+ format->u.audio.format = WG_AUDIO_FORMAT_AAC; -+ -+ if (SUCCEEDED(IMFMediaType_GetBlobSize(type, &MF_MT_USER_DATA, &user_data_size))) -+ { -+ user_data = malloc(user_data_size); -+ if (SUCCEEDED(IMFMediaType_GetBlob(type, &MF_MT_USER_DATA, user_data, user_data_size, NULL))) -+ { -+ struct { -+ WORD payload_type; -+ WORD indication; -+ WORD type; -+ WORD reserved1; -+ DWORD reserved2; -+ } *aac_info = (void *) user_data; -+ -+ format->u.audio.compressed.aac.payload_type = aac_info->payload_type; -+ format->u.audio.compressed.aac.indication = aac_info->indication; -+ -+ /* Audio specific config is stored at after HEAACWAVEINFO in MF_MT_USER_DATA -+ https://docs.microsoft.com/en-us/windows/win32/api/mmreg/ns-mmreg-heaacwaveformat */ -+ if (user_data_size > 12) -+ { -+ user_data += 12; -+ user_data_size -= 12; -+ -+ if (user_data_size > sizeof(format->u.audio.compressed.aac.audio_specifc_config)) -+ { -+ FIXME("Encountered Audio-Specific-Config with a size larger than we support %u\n", user_data_size); -+ user_data_size = sizeof(format->u.audio.compressed.aac.audio_specifc_config); -+ } -+ -+ memcpy(format->u.audio.compressed.aac.audio_specifc_config, user_data, user_data_size); -+ format->u.audio.compressed.aac.asp_size = user_data_size; -+ } -+ -+ } -+ } -+ -+ if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_AAC_PAYLOAD_TYPE, &payload_type))) -+ format->u.audio.compressed.aac.payload_type = payload_type; -+ -+ if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, &indication))) -+ format->u.audio.compressed.aac.indication = indication; -+ -+ return; -+ } -+ - for (i = 0; i < ARRAY_SIZE(audio_formats); ++i) - { - if (IsEqualGUID(&subtype, audio_formats[i].subtype) && depth == audio_formats[i].depth) -diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c -index 0328b5ed4f5..8ea9291904e 100644 ---- a/dlls/winegstreamer/quartz_parser.c -+++ b/dlls/winegstreamer/quartz_parser.c -@@ -100,6 +100,7 @@ static bool amt_from_wg_format_audio(AM_MEDIA_TYPE *mt, const struct wg_format * - switch (format->u.audio.format) - { - case WG_AUDIO_FORMAT_UNKNOWN: -+ case WG_AUDIO_FORMAT_AAC: - return false; - - case WG_AUDIO_FORMAT_MPEG1_LAYER1: -@@ -313,6 +314,7 @@ unsigned int wg_format_get_max_size(const struct wg_format *format) - case WG_AUDIO_FORMAT_MPEG1_LAYER3: - return 40000; - -+ case WG_AUDIO_FORMAT_AAC: - case WG_AUDIO_FORMAT_UNKNOWN: - FIXME("Cannot guess maximum sample size for unknown audio format.\n"); - return 0; -diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h -index f3db631d16d..d9c675ea873 100644 ---- a/dlls/winegstreamer/unixlib.h -+++ b/dlls/winegstreamer/unixlib.h -@@ -92,11 +92,27 @@ struct wg_format - WG_AUDIO_FORMAT_MPEG1_LAYER1, - WG_AUDIO_FORMAT_MPEG1_LAYER2, - WG_AUDIO_FORMAT_MPEG1_LAYER3, -+ -+ WG_AUDIO_FORMAT_AAC, - } format; - - uint32_t channels; - uint32_t channel_mask; /* In WinMM format. */ - uint32_t rate; -+ -+ union -+ { -+ struct -+ { -+ uint32_t payload_type; -+ uint32_t indication; -+ /* The definition of this structure is found in ISO/IEC 14496-3, -+ which we don't have access to, so we'll just keep -+ the size set to the largest instance we've seen used. */ -+ unsigned char audio_specifc_config[2]; -+ uint32_t asp_size; -+ } aac; -+ } compressed; - } audio; - } u; - }; -diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl -index 022f5f80980..630522f30b1 100644 ---- a/dlls/winegstreamer/winegstreamer_classes.idl -+++ b/dlls/winegstreamer/winegstreamer_classes.idl -@@ -79,3 +79,9 @@ coclass CWMADecMediaObject {}; - uuid(62ce7e72-4c71-4d20-b15d-452831a87d9d) - ] - coclass CMSH264DecoderMFT { } -+ -+[ -+ threading(both), -+ uuid(32d186a7-218f-4c75-8876-dd77273a8999) -+] -+coclass CMSAACDecMFT { } --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0024-winegstreamer-Rename-GStreamer-objects-to-be-more-ge.patch b/patches/mfplat-streaming-support/0024-winegstreamer-Rename-GStreamer-objects-to-be-more-ge.patch deleted file mode 100644 index d1aaf2c1..00000000 --- a/patches/mfplat-streaming-support/0024-winegstreamer-Rename-GStreamer-objects-to-be-more-ge.patch +++ /dev/null @@ -1,45 +0,0 @@ -From 2b8e7b14bfb8ad19d767bb378b24869f574f04f5 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Fri, 19 Mar 2021 17:00:51 -0400 -Subject: [PATCH 24/88] winegstreamer: Rename GStreamer objects to be more - generic. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/wg_parser.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index c2141fae2af..1d34437318e 100644 ---- a/dlls/winegstreamer/wg_parser.c -+++ b/dlls/winegstreamer/wg_parser.c -@@ -1196,7 +1196,7 @@ static struct wg_parser_stream *create_stream(struct wg_parser *parser) - pthread_cond_init(&stream->event_cond, NULL); - pthread_cond_init(&stream->event_empty_cond, NULL); - -- sprintf(pad_name, "qz_sink_%u", parser->stream_count); -+ sprintf(pad_name, "wine_sink_%u", parser->stream_count); - stream->my_sink = gst_pad_new(pad_name, GST_PAD_SINK); - gst_pad_set_element_private(stream->my_sink, stream); - gst_pad_set_chain_function(stream->my_sink, sink_chain_cb); -@@ -1753,7 +1753,7 @@ static gboolean src_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) - - static NTSTATUS wg_parser_connect(void *args) - { -- GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE("quartz_src", -+ GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE("wine_src", - GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY); - const struct wg_parser_connect_params *params = args; - struct wg_parser *parser = params->parser; -@@ -1772,7 +1772,7 @@ static NTSTATUS wg_parser_connect(void *args) - parser->container = gst_bin_new(NULL); - gst_element_set_bus(parser->container, parser->bus); - -- parser->my_src = gst_pad_new_from_static_template(&src_template, "quartz-src"); -+ parser->my_src = gst_pad_new_from_static_template(&src_template, "wine-src"); - gst_pad_set_getrange_function(parser->my_src, src_getrange_cb); - gst_pad_set_query_function(parser->my_src, src_query_cb); - gst_pad_set_activatemode_function(parser->my_src, src_activate_mode_cb); --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0026-winegstreamer-Implement-Get-Input-Output-StreamInfo-.patch b/patches/mfplat-streaming-support/0026-winegstreamer-Implement-Get-Input-Output-StreamInfo-.patch deleted file mode 100644 index 9cb30c2f..00000000 --- a/patches/mfplat-streaming-support/0026-winegstreamer-Implement-Get-Input-Output-StreamInfo-.patch +++ /dev/null @@ -1,73 +0,0 @@ -From 5eef24de0657d410169e9d6a3f0c62e7e1ebded3 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Wed, 17 Mar 2021 15:12:20 -0400 -Subject: [PATCH 26/88] winegstreamer: Implement ::Get(Input/Output)StreamInfo - for audio conversion transform. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/audioconvert.c | 42 ++++++++++++++++++++++++++++--- - 1 file changed, 38 insertions(+), 4 deletions(-) - -diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c -index d5723cdf58f..56aa96770b7 100644 ---- a/dlls/winegstreamer/audioconvert.c -+++ b/dlls/winegstreamer/audioconvert.c -@@ -115,16 +115,50 @@ static HRESULT WINAPI audio_converter_GetStreamIDs(IMFTransform *iface, DWORD in - - static HRESULT WINAPI audio_converter_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info) - { -- FIXME("%p, %lu, %p.\n", iface, id, info); -+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface); - -- return E_NOTIMPL; -+ TRACE("%p, %lu, %p.\n", iface, id, info); -+ -+ if (id != 0) -+ return MF_E_INVALIDSTREAMNUMBER; -+ -+ info->dwFlags = MFT_INPUT_STREAM_WHOLE_SAMPLES | MFT_INPUT_STREAM_DOES_NOT_ADDREF; -+ info->cbMaxLookahead = 0; -+ info->cbAlignment = 0; -+ info->hnsMaxLatency = 0; -+ info->cbSize = 0; -+ -+ EnterCriticalSection(&converter->cs); -+ -+ if (converter->input_type) -+ IMFMediaType_GetUINT32(converter->input_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &info->cbSize); -+ -+ LeaveCriticalSection(&converter->cs); -+ -+ return S_OK; - } - - static HRESULT WINAPI audio_converter_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info) - { -- FIXME("%p. %lu, %p.\n", iface, id, info); -+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface); - -- return E_NOTIMPL; -+ TRACE("%p. %lu, %p.\n", iface, id, info); -+ -+ if (id != 0) -+ return MF_E_INVALIDSTREAMNUMBER; -+ -+ info->dwFlags = MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES | MFT_OUTPUT_STREAM_WHOLE_SAMPLES; -+ info->cbAlignment = 0; -+ info->cbSize = 0; -+ -+ EnterCriticalSection(&converter->cs); -+ -+ if (converter->output_type) -+ IMFMediaType_GetUINT32(converter->output_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &info->cbSize); -+ -+ LeaveCriticalSection(&converter->cs); -+ -+ return S_OK; - } - - static HRESULT WINAPI audio_converter_GetAttributes(IMFTransform *iface, IMFAttributes **attributes) --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0027-winegstreamer-Semi-stub-Get-Attributes-functions-for.patch b/patches/mfplat-streaming-support/0027-winegstreamer-Semi-stub-Get-Attributes-functions-for.patch deleted file mode 100644 index 04626c92..00000000 --- a/patches/mfplat-streaming-support/0027-winegstreamer-Semi-stub-Get-Attributes-functions-for.patch +++ /dev/null @@ -1,101 +0,0 @@ -From baf0a7e95e8601833e46769c16745d742431b1a4 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Wed, 17 Mar 2021 15:19:32 -0400 -Subject: [PATCH 27/88] winegstreamer: Semi-stub Get*Attributes functions for - audio converter transform. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/audioconvert.c | 39 +++++++++++++++++++++++++++---- - 1 file changed, 35 insertions(+), 4 deletions(-) - -diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c -index 56aa96770b7..a4258c6aecd 100644 ---- a/dlls/winegstreamer/audioconvert.c -+++ b/dlls/winegstreamer/audioconvert.c -@@ -35,6 +35,7 @@ struct audio_converter - IMFMediaType *input_type; - IMFMediaType *output_type; - CRITICAL_SECTION cs; -+ IMFAttributes *attributes, *output_attributes; - }; - - static struct audio_converter *impl_audio_converter_from_IMFTransform(IMFTransform *iface) -@@ -80,6 +81,10 @@ static ULONG WINAPI audio_converter_Release(IMFTransform *iface) - { - transform->cs.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&transform->cs); -+ if (transform->attributes) -+ IMFAttributes_Release(transform->attributes); -+ if (transform->output_attributes) -+ IMFAttributes_Release(transform->output_attributes); - free(transform); - } - -@@ -163,9 +168,14 @@ static HRESULT WINAPI audio_converter_GetOutputStreamInfo(IMFTransform *iface, D - - static HRESULT WINAPI audio_converter_GetAttributes(IMFTransform *iface, IMFAttributes **attributes) - { -- FIXME("%p, %p.\n", iface, attributes); -+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface); - -- return E_NOTIMPL; -+ TRACE("%p, %p.\n", iface, attributes); -+ -+ *attributes = converter->attributes; -+ IMFAttributes_AddRef(*attributes); -+ -+ return S_OK; - } - - static HRESULT WINAPI audio_converter_GetInputStreamAttributes(IMFTransform *iface, DWORD id, -@@ -179,9 +189,17 @@ static HRESULT WINAPI audio_converter_GetInputStreamAttributes(IMFTransform *ifa - static HRESULT WINAPI audio_converter_GetOutputStreamAttributes(IMFTransform *iface, DWORD id, - IMFAttributes **attributes) - { -- FIXME("%p, %lu, %p.\n", iface, id, attributes); -+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface); - -- return E_NOTIMPL; -+ TRACE("%p, %lu, %p.\n", iface, id, attributes); -+ -+ if (id != 0) -+ return MF_E_INVALIDSTREAMNUMBER; -+ -+ *attributes = converter->output_attributes; -+ IMFAttributes_AddRef(*attributes); -+ -+ return S_OK; - } - - static HRESULT WINAPI audio_converter_DeleteInputStream(IMFTransform *iface, DWORD id) -@@ -601,6 +619,7 @@ static const IMFTransformVtbl audio_converter_vtbl = - HRESULT audio_converter_create(REFIID riid, void **ret) - { - struct audio_converter *object; -+ HRESULT hr; - - TRACE("%s %p\n", debugstr_guid(riid), ret); - -@@ -613,6 +632,18 @@ HRESULT audio_converter_create(REFIID riid, void **ret) - InitializeCriticalSection(&object->cs); - object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": audio_converter_lock"); - -+ if (FAILED(hr = MFCreateAttributes(&object->attributes, 0))) -+ { -+ IMFTransform_Release(&object->IMFTransform_iface); -+ return hr; -+ } -+ -+ if (FAILED(hr = MFCreateAttributes(&object->output_attributes, 0))) -+ { -+ IMFTransform_Release(&object->IMFTransform_iface); -+ return hr; -+ } -+ - *ret = &object->IMFTransform_iface; - return S_OK; - } --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0028-winegstreamer-Introduce-color-conversion-transform.patch b/patches/mfplat-streaming-support/0028-winegstreamer-Introduce-color-conversion-transform.patch deleted file mode 100644 index d6a1471c..00000000 --- a/patches/mfplat-streaming-support/0028-winegstreamer-Introduce-color-conversion-transform.patch +++ /dev/null @@ -1,388 +0,0 @@ -From aec53333c8c27975efa46d99d8e87cd91d93ec33 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Wed, 17 Mar 2021 15:35:20 -0400 -Subject: [PATCH 28/88] winegstreamer: Introduce color conversion transform. - -Serves as a wrapper of videoconvert, and exposes the CColorConverterDMO MFT interface. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/Makefile.in | 1 + - dlls/winegstreamer/colorconvert.c | 298 +++++++++++++++++++ - dlls/winegstreamer/gst_private.h | 1 + - dlls/winegstreamer/mfplat.c | 1 + - dlls/winegstreamer/winegstreamer_classes.idl | 6 + - include/wmcodecdsp.idl | 5 + - 6 files changed, 312 insertions(+) - create mode 100644 dlls/winegstreamer/colorconvert.c - -diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in -index 3da8c614ed2..74bcc35364b 100644 ---- a/dlls/winegstreamer/Makefile.in -+++ b/dlls/winegstreamer/Makefile.in -@@ -8,6 +8,7 @@ EXTRALIBS = $(GSTREAMER_LIBS) $(PTHREAD_LIBS) - - C_SRCS = \ - audioconvert.c \ -+ colorconvert.c \ - decode_transform.c \ - main.c \ - media_source.c \ -diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c -new file mode 100644 -index 00000000000..1f0d061a30c ---- /dev/null -+++ b/dlls/winegstreamer/colorconvert.c -@@ -0,0 +1,298 @@ -+/* GStreamer Color Converter -+ * -+ * Copyright 2020 Derek Lesho -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+#include "gst_private.h" -+ -+#include "mfapi.h" -+#include "mferror.h" -+ -+#include "wine/debug.h" -+ -+WINE_DEFAULT_DEBUG_CHANNEL(mfplat); -+ -+struct color_converter -+{ -+ IMFTransform IMFTransform_iface; -+ LONG refcount; -+}; -+ -+static struct color_converter *impl_color_converter_from_IMFTransform(IMFTransform *iface) -+{ -+ return CONTAINING_RECORD(iface, struct color_converter, IMFTransform_iface); -+} -+ -+static HRESULT WINAPI color_converter_QueryInterface(IMFTransform *iface, REFIID riid, void **obj) -+{ -+ TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); -+ -+ if (IsEqualGUID(riid, &IID_IMFTransform) || -+ IsEqualGUID(riid, &IID_IUnknown)) -+ { -+ *obj = iface; -+ IMFTransform_AddRef(iface); -+ return S_OK; -+ } -+ -+ WARN("Unsupported %s.\n", debugstr_guid(riid)); -+ *obj = NULL; -+ return E_NOINTERFACE; -+} -+ -+static ULONG WINAPI color_converter_AddRef(IMFTransform *iface) -+{ -+ struct color_converter *transform = impl_color_converter_from_IMFTransform(iface); -+ ULONG refcount = InterlockedIncrement(&transform->refcount); -+ -+ TRACE("%p, refcount %u.\n", iface, refcount); -+ -+ return refcount; -+} -+ -+static ULONG WINAPI color_converter_Release(IMFTransform *iface) -+{ -+ struct color_converter *transform = impl_color_converter_from_IMFTransform(iface); -+ ULONG refcount = InterlockedDecrement(&transform->refcount); -+ -+ TRACE("%p, refcount %u.\n", iface, refcount); -+ -+ if (!refcount) -+ { -+ free(transform); -+ } -+ -+ return refcount; -+} -+ -+static HRESULT WINAPI color_converter_GetStreamLimits(IMFTransform *iface, DWORD *input_minimum, DWORD *input_maximum, -+ DWORD *output_minimum, DWORD *output_maximum) -+{ -+ TRACE("%p, %p, %p, %p, %p.\n", iface, input_minimum, input_maximum, output_minimum, output_maximum); -+ -+ *input_minimum = *input_maximum = *output_minimum = *output_maximum = 1; -+ -+ return S_OK; -+} -+ -+static HRESULT WINAPI color_converter_GetStreamCount(IMFTransform *iface, DWORD *inputs, DWORD *outputs) -+{ -+ TRACE("%p, %p, %p.\n", iface, inputs, outputs); -+ -+ *inputs = *outputs = 1; -+ -+ return S_OK; -+} -+ -+static HRESULT WINAPI color_converter_GetStreamIDs(IMFTransform *iface, DWORD input_size, DWORD *inputs, -+ DWORD output_size, DWORD *outputs) -+{ -+ TRACE("%p %u %p %u %p.\n", iface, input_size, inputs, output_size, outputs); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI color_converter_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info) -+{ -+ FIXME("%p %u %p.\n", iface, id, info); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI color_converter_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info) -+{ -+ FIXME("%p %u %p.\n", iface, id, info); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI color_converter_GetAttributes(IMFTransform *iface, IMFAttributes **attributes) -+{ -+ FIXME("%p, %p.\n", iface, attributes); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI color_converter_GetInputStreamAttributes(IMFTransform *iface, DWORD id, -+ IMFAttributes **attributes) -+{ -+ FIXME("%p, %u, %p.\n", iface, id, attributes); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI color_converter_GetOutputStreamAttributes(IMFTransform *iface, DWORD id, -+ IMFAttributes **attributes) -+{ -+ FIXME("%p, %u, %p.\n", iface, id, attributes); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI color_converter_DeleteInputStream(IMFTransform *iface, DWORD id) -+{ -+ TRACE("%p, %u.\n", iface, id); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI color_converter_AddInputStreams(IMFTransform *iface, DWORD streams, DWORD *ids) -+{ -+ TRACE("%p, %u, %p.\n", iface, streams, ids); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI color_converter_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index, -+ IMFMediaType **type) -+{ -+ FIXME("%p, %u, %u, %p.\n", iface, id, index, type); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI color_converter_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index, -+ IMFMediaType **type) -+{ -+ FIXME("%p, %u, %u, %p.\n", iface, id, index, type); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) -+{ -+ FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI color_converter_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) -+{ -+ FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI color_converter_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) -+{ -+ FIXME("%p, %u, %p.\n", iface, id, type); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI color_converter_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) -+{ -+ FIXME("%p, %u, %p.\n", iface, id, type); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI color_converter_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags) -+{ -+ FIXME("%p, %u, %p.\n", iface, id, flags); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI color_converter_GetOutputStatus(IMFTransform *iface, DWORD *flags) -+{ -+ FIXME("%p, %p.\n", iface, flags); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI color_converter_SetOutputBounds(IMFTransform *iface, LONGLONG lower, LONGLONG upper) -+{ -+ FIXME("%p, %s, %s.\n", iface, wine_dbgstr_longlong(lower), wine_dbgstr_longlong(upper)); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI color_converter_ProcessEvent(IMFTransform *iface, DWORD id, IMFMediaEvent *event) -+{ -+ TRACE("%p, %u, %p.\n", iface, id, event); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI color_converter_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param) -+{ -+ FIXME("%p, %u %lu.\n", iface, message, param); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI color_converter_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags) -+{ -+ FIXME("%p, %u, %p, %#x.\n", iface, id, sample, flags); -+ -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI color_converter_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count, -+ MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status) -+{ -+ FIXME("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status); -+ -+ return E_NOTIMPL; -+} -+ -+static const IMFTransformVtbl color_converter_vtbl = -+{ -+ color_converter_QueryInterface, -+ color_converter_AddRef, -+ color_converter_Release, -+ color_converter_GetStreamLimits, -+ color_converter_GetStreamCount, -+ color_converter_GetStreamIDs, -+ color_converter_GetInputStreamInfo, -+ color_converter_GetOutputStreamInfo, -+ color_converter_GetAttributes, -+ color_converter_GetInputStreamAttributes, -+ color_converter_GetOutputStreamAttributes, -+ color_converter_DeleteInputStream, -+ color_converter_AddInputStreams, -+ color_converter_GetInputAvailableType, -+ color_converter_GetOutputAvailableType, -+ color_converter_SetInputType, -+ color_converter_SetOutputType, -+ color_converter_GetInputCurrentType, -+ color_converter_GetOutputCurrentType, -+ color_converter_GetInputStatus, -+ color_converter_GetOutputStatus, -+ color_converter_SetOutputBounds, -+ color_converter_ProcessEvent, -+ color_converter_ProcessMessage, -+ color_converter_ProcessInput, -+ color_converter_ProcessOutput, -+}; -+ -+HRESULT color_converter_create(REFIID riid, void **ret) -+{ -+ struct color_converter *object; -+ -+ TRACE("%s %p\n", debugstr_guid(riid), ret); -+ -+ if (!(object = calloc(1, sizeof(*object)))) -+ return E_OUTOFMEMORY; -+ -+ object->IMFTransform_iface.lpVtbl = &color_converter_vtbl; -+ object->refcount = 1; -+ -+ *ret = &object->IMFTransform_iface; -+ return S_OK; -+} -diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h -index 73d5e88b164..d3271518f8f 100644 ---- a/dlls/winegstreamer/gst_private.h -+++ b/dlls/winegstreamer/gst_private.h -@@ -118,6 +118,7 @@ void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format); - HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj); - - HRESULT audio_converter_create(REFIID riid, void **ret); -+HRESULT color_converter_create(REFIID riid, void **ret); - - enum decoder_type - { -diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index e22cd51c8a9..6f6ec956b2b 100644 ---- a/dlls/winegstreamer/mfplat.c -+++ b/dlls/winegstreamer/mfplat.c -@@ -413,6 +413,7 @@ class_objects[] = - { &CLSID_VideoProcessorMFT, &video_processor_create }, - { &CLSID_GStreamerByteStreamHandler, &winegstreamer_stream_handler_create }, - { &CLSID_WINEAudioConverter, &audio_converter_create }, -+ { &CLSID_CColorConvertDMO, &color_converter_create }, - { &CLSID_MSH264DecoderMFT, &h264_decoder_create }, - { &CLSID_MSAACDecMFT, &aac_decoder_create }, - }; -diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl -index 630522f30b1..5762430a5cd 100644 ---- a/dlls/winegstreamer/winegstreamer_classes.idl -+++ b/dlls/winegstreamer/winegstreamer_classes.idl -@@ -85,3 +85,9 @@ coclass CMSH264DecoderMFT { } - uuid(32d186a7-218f-4c75-8876-dd77273a8999) - ] - coclass CMSAACDecMFT { } -+ -+[ -+ threading(both), -+ uuid(98230571-0087-4204-b020-3282538e57d3) -+] -+coclass CColorConvertDMO { } -diff --git a/include/wmcodecdsp.idl b/include/wmcodecdsp.idl -index ae2a42419b4..711179fe1d2 100644 ---- a/include/wmcodecdsp.idl -+++ b/include/wmcodecdsp.idl -@@ -49,3 +49,8 @@ coclass CWMADecMediaObject {}; - uuid(93af0c51-2275-45d2-a35b-f2ba21caed00) - ] - coclass AACMFTEncoder {}; -+ -+[ -+ uuid(98230571-0087-4204-b020-3282538e57d3) -+] -+coclass CColorConvertDMO {} --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0030-winegstreamer-Implement-GetInputAvailableType-for-co.patch b/patches/mfplat-streaming-support/0030-winegstreamer-Implement-GetInputAvailableType-for-co.patch deleted file mode 100644 index ac390fe7..00000000 --- a/patches/mfplat-streaming-support/0030-winegstreamer-Implement-GetInputAvailableType-for-co.patch +++ /dev/null @@ -1,81 +0,0 @@ -From e0a8b0048e9507ad457cb6b3b9a535331528dd71 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Wed, 17 Mar 2021 15:41:33 -0400 -Subject: [PATCH 30/88] winegstreamer: Implement ::GetInputAvailableType for - color conversion transform. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/colorconvert.c | 48 +++++++++++++++++++++++++++++-- - 1 file changed, 46 insertions(+), 2 deletions(-) - -diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c -index 1f0d061a30c..078782daaed 100644 ---- a/dlls/winegstreamer/colorconvert.c -+++ b/dlls/winegstreamer/colorconvert.c -@@ -26,6 +26,24 @@ - - WINE_DEFAULT_DEBUG_CHANNEL(mfplat); - -+static const GUID *raw_types[] = { -+ &MFVideoFormat_RGB24, -+ &MFVideoFormat_RGB32, -+ &MFVideoFormat_RGB555, -+ &MFVideoFormat_RGB8, -+ &MFVideoFormat_AYUV, -+ &MFVideoFormat_I420, -+ &MFVideoFormat_IYUV, -+ &MFVideoFormat_NV11, -+ &MFVideoFormat_NV12, -+ &MFVideoFormat_UYVY, -+ &MFVideoFormat_v216, -+ &MFVideoFormat_v410, -+ &MFVideoFormat_YUY2, -+ &MFVideoFormat_YVYU, -+ &MFVideoFormat_YVYU, -+}; -+ - struct color_converter - { - IMFTransform IMFTransform_iface; -@@ -160,9 +178,35 @@ static HRESULT WINAPI color_converter_AddInputStreams(IMFTransform *iface, DWORD - static HRESULT WINAPI color_converter_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index, - IMFMediaType **type) - { -- FIXME("%p, %u, %u, %p.\n", iface, id, index, type); -+ IMFMediaType *ret; -+ HRESULT hr; - -- return E_NOTIMPL; -+ TRACE("%p, %u, %u, %p.\n", iface, id, index, type); -+ -+ if (id != 0) -+ return MF_E_INVALIDSTREAMNUMBER; -+ -+ if (index >= ARRAY_SIZE(raw_types)) -+ return MF_E_NO_MORE_TYPES; -+ -+ if (FAILED(hr = MFCreateMediaType(&ret))) -+ return hr; -+ -+ if (FAILED(hr = IMFMediaType_SetGUID(ret, &MF_MT_MAJOR_TYPE, &MFMediaType_Video))) -+ { -+ IMFMediaType_Release(ret); -+ return hr; -+ } -+ -+ if (FAILED(hr = IMFMediaType_SetGUID(ret, &MF_MT_SUBTYPE, raw_types[index]))) -+ { -+ IMFMediaType_Release(ret); -+ return hr; -+ } -+ -+ *type = ret; -+ -+ return S_OK; - } - - static HRESULT WINAPI color_converter_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index, --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0031-winegstreamer-Implement-SetInputType-for-color-conve.patch b/patches/mfplat-streaming-support/0031-winegstreamer-Implement-SetInputType-for-color-conve.patch deleted file mode 100644 index 5057765c..00000000 --- a/patches/mfplat-streaming-support/0031-winegstreamer-Implement-SetInputType-for-color-conve.patch +++ /dev/null @@ -1,122 +0,0 @@ -From c396ea3ccf731d454fddb3a3f7c8e04dc0e5be8b Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Wed, 17 Mar 2021 16:01:18 -0400 -Subject: [PATCH 31/88] winegstreamer: Implement ::SetInputType for color - conversion transform. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/colorconvert.c | 75 ++++++++++++++++++++++++++++++- - 1 file changed, 73 insertions(+), 2 deletions(-) - -diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c -index 078782daaed..06186ed7846 100644 ---- a/dlls/winegstreamer/colorconvert.c -+++ b/dlls/winegstreamer/colorconvert.c -@@ -48,6 +48,8 @@ struct color_converter - { - IMFTransform IMFTransform_iface; - LONG refcount; -+ IMFMediaType *input_type; -+ CRITICAL_SECTION cs; - }; - - static struct color_converter *impl_color_converter_from_IMFTransform(IMFTransform *iface) -@@ -91,6 +93,8 @@ static ULONG WINAPI color_converter_Release(IMFTransform *iface) - - if (!refcount) - { -+ transform->cs.DebugInfo->Spare[0] = 0; -+ DeleteCriticalSection(&transform->cs); - free(transform); - } - -@@ -219,9 +223,73 @@ static HRESULT WINAPI color_converter_GetOutputAvailableType(IMFTransform *iface - - static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) - { -- FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags); -+ struct color_converter *converter = impl_color_converter_from_IMFTransform(iface); -+ GUID major_type, subtype; -+ unsigned int i; -+ HRESULT hr; - -- return E_NOTIMPL; -+ TRACE("%p, %u, %p, %#x.\n", iface, id, type, flags); -+ -+ if (id != 0) -+ return MF_E_INVALIDSTREAMNUMBER; -+ -+ if (!type) -+ { -+ if (flags & MFT_SET_TYPE_TEST_ONLY) -+ return S_OK; -+ -+ EnterCriticalSection(&converter->cs); -+ -+ if (converter->input_type) -+ { -+ IMFMediaType_Release(converter->input_type); -+ converter->input_type = NULL; -+ } -+ -+ LeaveCriticalSection(&converter->cs); -+ -+ return S_OK; -+ } -+ -+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type))) -+ return MF_E_INVALIDTYPE; -+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype))) -+ return MF_E_INVALIDTYPE; -+ -+ if (!IsEqualGUID(&major_type, &MFMediaType_Video)) -+ return MF_E_INVALIDTYPE; -+ -+ for (i = 0; i < ARRAY_SIZE(raw_types); i++) -+ { -+ if (IsEqualGUID(&subtype, raw_types[i])) -+ break; -+ } -+ -+ if (i == ARRAY_SIZE(raw_types)) -+ return MF_E_INVALIDTYPE; -+ -+ if (flags & MFT_SET_TYPE_TEST_ONLY) -+ return S_OK; -+ -+ EnterCriticalSection(&converter->cs); -+ -+ hr = S_OK; -+ -+ if (!converter->input_type) -+ hr = MFCreateMediaType(&converter->input_type); -+ -+ if (SUCCEEDED(hr)) -+ hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->input_type); -+ -+ if (FAILED(hr)) -+ { -+ IMFMediaType_Release(converter->input_type); -+ converter->input_type = NULL; -+ } -+ -+ LeaveCriticalSection(&converter->cs); -+ -+ return hr; - } - - static HRESULT WINAPI color_converter_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) -@@ -337,6 +405,9 @@ HRESULT color_converter_create(REFIID riid, void **ret) - object->IMFTransform_iface.lpVtbl = &color_converter_vtbl; - object->refcount = 1; - -+ InitializeCriticalSection(&object->cs); -+ object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": color_converter_lock"); -+ - *ret = &object->IMFTransform_iface; - return S_OK; - } --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0032-winegstreamer-Implement-GetOutputAvailableType-for-c.patch b/patches/mfplat-streaming-support/0032-winegstreamer-Implement-GetOutputAvailableType-for-c.patch deleted file mode 100644 index f5d17577..00000000 --- a/patches/mfplat-streaming-support/0032-winegstreamer-Implement-GetOutputAvailableType-for-c.patch +++ /dev/null @@ -1,64 +0,0 @@ -From c5ccac06781882e1debd710e2f0c3e1aaf46565a Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Wed, 17 Mar 2021 16:04:31 -0400 -Subject: [PATCH 32/88] winegstreamer: Implement ::GetOutputAvailableType for - color conversion transform. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/colorconvert.c | 38 +++++++++++++++++++++++++++++-- - 1 file changed, 36 insertions(+), 2 deletions(-) - -diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c -index 06186ed7846..6d7064a4482 100644 ---- a/dlls/winegstreamer/colorconvert.c -+++ b/dlls/winegstreamer/colorconvert.c -@@ -216,9 +216,43 @@ static HRESULT WINAPI color_converter_GetInputAvailableType(IMFTransform *iface, - static HRESULT WINAPI color_converter_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index, - IMFMediaType **type) - { -- FIXME("%p, %u, %u, %p.\n", iface, id, index, type); -+ struct color_converter *converter = impl_color_converter_from_IMFTransform(iface); -+ IMFMediaType *ret; -+ HRESULT hr; - -- return E_NOTIMPL; -+ TRACE("%p, %u, %u, %p.\n", iface, id, index, type); -+ -+ if (id != 0) -+ return MF_E_INVALIDSTREAMNUMBER; -+ -+ if (index >= ARRAY_SIZE(raw_types)) -+ return MF_E_NO_MORE_TYPES; -+ -+ if (FAILED(hr = MFCreateMediaType(&ret))) -+ return hr; -+ -+ EnterCriticalSection(&converter->cs); -+ -+ if (converter->input_type) -+ IMFMediaType_CopyAllItems(converter->input_type, (IMFAttributes *) ret); -+ -+ LeaveCriticalSection(&converter->cs); -+ -+ if (FAILED(hr = IMFMediaType_SetGUID(ret, &MF_MT_MAJOR_TYPE, &MFMediaType_Video))) -+ { -+ IMFMediaType_Release(ret); -+ return hr; -+ } -+ -+ if (FAILED(hr = IMFMediaType_SetGUID(ret, &MF_MT_SUBTYPE, raw_types[index]))) -+ { -+ IMFMediaType_Release(ret); -+ return hr; -+ } -+ -+ *type = ret; -+ -+ return S_OK; - } - - static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0033-winegstreamer-Implement-SetOutputType-for-color-conv.patch b/patches/mfplat-streaming-support/0033-winegstreamer-Implement-SetOutputType-for-color-conv.patch deleted file mode 100644 index 349d9e6b..00000000 --- a/patches/mfplat-streaming-support/0033-winegstreamer-Implement-SetOutputType-for-color-conv.patch +++ /dev/null @@ -1,153 +0,0 @@ -From 75d114aad6addbf24d1ecc22ca223aae02586b9c Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Wed, 17 Mar 2021 16:26:28 -0400 -Subject: [PATCH 33/88] winegstreamer: Implement ::SetOutputType for color - conversion transform. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/colorconvert.c | 99 ++++++++++++++++++++++++++++++- - 1 file changed, 97 insertions(+), 2 deletions(-) - -diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c -index 6d7064a4482..e001c6c827e 100644 ---- a/dlls/winegstreamer/colorconvert.c -+++ b/dlls/winegstreamer/colorconvert.c -@@ -49,6 +49,7 @@ struct color_converter - IMFTransform IMFTransform_iface; - LONG refcount; - IMFMediaType *input_type; -+ IMFMediaType *output_type; - CRITICAL_SECTION cs; - }; - -@@ -95,6 +96,8 @@ static ULONG WINAPI color_converter_Release(IMFTransform *iface) - { - transform->cs.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&transform->cs); -+ if (transform->output_type) -+ IMFMediaType_Release(transform->output_type); - free(transform); - } - -@@ -258,6 +261,7 @@ static HRESULT WINAPI color_converter_GetOutputAvailableType(IMFTransform *iface - static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) - { - struct color_converter *converter = impl_color_converter_from_IMFTransform(iface); -+ UINT64 input_framesize, output_framesize; - GUID major_type, subtype; - unsigned int i; - HRESULT hr; -@@ -302,6 +306,19 @@ static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id - if (i == ARRAY_SIZE(raw_types)) - return MF_E_INVALIDTYPE; - -+ EnterCriticalSection(&converter->cs); -+ -+ if(converter->output_type -+ && SUCCEEDED(IMFMediaType_GetUINT64(converter->output_type, &MF_MT_FRAME_SIZE, &output_framesize)) -+ && SUCCEEDED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &input_framesize)) -+ && input_framesize != output_framesize) -+ { -+ LeaveCriticalSection(&converter->cs); -+ return MF_E_INVALIDTYPE; -+ } -+ -+ LeaveCriticalSection(&converter->cs); -+ - if (flags & MFT_SET_TYPE_TEST_ONLY) - return S_OK; - -@@ -328,9 +345,87 @@ static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id - - static HRESULT WINAPI color_converter_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) - { -- FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags); -+ struct color_converter *converter = impl_color_converter_from_IMFTransform(iface); -+ UINT64 input_framesize, output_framesize; -+ GUID major_type, subtype; -+ unsigned int i; -+ HRESULT hr; - -- return E_NOTIMPL; -+ TRACE("%p, %u, %p, %#x.\n", iface, id, type, flags); -+ -+ if (id != 0) -+ return MF_E_INVALIDSTREAMNUMBER; -+ -+ if (!type) -+ { -+ if (flags & MFT_SET_TYPE_TEST_ONLY) -+ return S_OK; -+ -+ EnterCriticalSection(&converter->cs); -+ -+ if (converter->output_type) -+ { -+ IMFMediaType_Release(converter->output_type); -+ converter->output_type = NULL; -+ } -+ -+ LeaveCriticalSection(&converter->cs); -+ -+ return S_OK; -+ } -+ -+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type))) -+ return MF_E_INVALIDTYPE; -+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype))) -+ return MF_E_INVALIDTYPE; -+ -+ if (!IsEqualGUID(&major_type, &MFMediaType_Video)) -+ return MF_E_INVALIDTYPE; -+ -+ for (i = 0; i < ARRAY_SIZE(raw_types); i++) -+ { -+ if (IsEqualGUID(&subtype, raw_types[i])) -+ break; -+ } -+ -+ if (i == ARRAY_SIZE(raw_types)) -+ return MF_E_INVALIDTYPE; -+ -+ EnterCriticalSection(&converter->cs); -+ -+ if(converter->input_type -+ && SUCCEEDED(IMFMediaType_GetUINT64(converter->input_type, &MF_MT_FRAME_SIZE, &input_framesize)) -+ && SUCCEEDED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &output_framesize)) -+ && input_framesize != output_framesize) -+ { -+ LeaveCriticalSection(&converter->cs); -+ return MF_E_INVALIDTYPE; -+ } -+ -+ LeaveCriticalSection(&converter->cs); -+ -+ if (flags & MFT_SET_TYPE_TEST_ONLY) -+ return S_OK; -+ -+ EnterCriticalSection(&converter->cs); -+ -+ hr = S_OK; -+ -+ if (!converter->output_type) -+ hr = MFCreateMediaType(&converter->output_type); -+ -+ if (SUCCEEDED(hr)) -+ hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->output_type); -+ -+ if (FAILED(hr)) -+ { -+ IMFMediaType_Release(converter->output_type); -+ converter->output_type = NULL; -+ } -+ -+ LeaveCriticalSection(&converter->cs); -+ -+ return S_OK; - } - - static HRESULT WINAPI color_converter_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0034-winegstreamer-Implement-ProcessMessage-for-color-con.patch b/patches/mfplat-streaming-support/0034-winegstreamer-Implement-ProcessMessage-for-color-con.patch deleted file mode 100644 index ea7b26d8..00000000 --- a/patches/mfplat-streaming-support/0034-winegstreamer-Implement-ProcessMessage-for-color-con.patch +++ /dev/null @@ -1,38 +0,0 @@ -From 112153e5fd44f225c80b6abbec0bffa36da0bbf3 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Wed, 17 Mar 2021 16:50:47 -0400 -Subject: [PATCH 34/88] winegstreamer: Implement ::ProcessMessage for color - conversion MFT. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/colorconvert.c | 12 ++++++++++-- - 1 file changed, 10 insertions(+), 2 deletions(-) - -diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c -index e001c6c827e..0e8980659a5 100644 ---- a/dlls/winegstreamer/colorconvert.c -+++ b/dlls/winegstreamer/colorconvert.c -@@ -472,9 +472,17 @@ static HRESULT WINAPI color_converter_ProcessEvent(IMFTransform *iface, DWORD id - - static HRESULT WINAPI color_converter_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param) - { -- FIXME("%p, %u %lu.\n", iface, message, param); -+ TRACE("%p, %u %lu.\n", iface, message, param); - -- return E_NOTIMPL; -+ switch(message) -+ { -+ case MFT_MESSAGE_COMMAND_FLUSH: -+ case MFT_MESSAGE_NOTIFY_BEGIN_STREAMING: -+ return S_OK; -+ default: -+ FIXME("Unhandled message type %x.\n", message); -+ return E_NOTIMPL; -+ } - } - - static HRESULT WINAPI color_converter_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags) --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0035-winegstreamer-Implement-Get-Input-Output-StreamInfo-.patch b/patches/mfplat-streaming-support/0035-winegstreamer-Implement-Get-Input-Output-StreamInfo-.patch deleted file mode 100644 index 9d056a3d..00000000 --- a/patches/mfplat-streaming-support/0035-winegstreamer-Implement-Get-Input-Output-StreamInfo-.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 6a2f654147260fa022d1f045506dd4ed5c6ec1e4 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Wed, 17 Mar 2021 17:01:11 -0400 -Subject: [PATCH 35/88] winegstreamer: Implement ::Get(Input/Output)StreamInfo - for color conversion transform. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/colorconvert.c | 64 +++++++++++++++++++++++++++++-- - 1 file changed, 60 insertions(+), 4 deletions(-) - -diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c -index 0e8980659a5..db4ca4e3fbe 100644 ---- a/dlls/winegstreamer/colorconvert.c -+++ b/dlls/winegstreamer/colorconvert.c -@@ -133,16 +133,72 @@ static HRESULT WINAPI color_converter_GetStreamIDs(IMFTransform *iface, DWORD in - - static HRESULT WINAPI color_converter_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info) - { -- FIXME("%p %u %p.\n", iface, id, info); -+ struct color_converter *converter = impl_color_converter_from_IMFTransform(iface); -+ UINT64 framesize; -+ GUID subtype; - -- return E_NOTIMPL; -+ TRACE("%p %u %p.\n", iface, id, info); -+ -+ if (id != 0) -+ return MF_E_INVALIDSTREAMNUMBER; -+ -+ info->dwFlags = MFT_INPUT_STREAM_WHOLE_SAMPLES | MFT_INPUT_STREAM_DOES_NOT_ADDREF | MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE; -+ info->cbMaxLookahead = 0; -+ info->cbAlignment = 0; -+ info->hnsMaxLatency = 0; -+ info->cbSize = 0; -+ -+ EnterCriticalSection(&converter->cs); -+ -+ if (converter->input_type) -+ { -+ if (SUCCEEDED(IMFMediaType_GetGUID(converter->input_type, &MF_MT_SUBTYPE, &subtype)) && -+ SUCCEEDED(IMFMediaType_GetUINT64(converter->input_type, &MF_MT_FRAME_SIZE, &framesize))) -+ { -+ MFCalculateImageSize(&subtype, framesize >> 32, (UINT32) framesize, &info->cbSize); -+ } -+ -+ if (!info->cbSize) -+ WARN("Failed to get desired input buffer size, the non-provided sample path will likely break\n"); -+ } -+ -+ LeaveCriticalSection(&converter->cs); -+ -+ return S_OK; - } - - static HRESULT WINAPI color_converter_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info) - { -- FIXME("%p %u %p.\n", iface, id, info); -+ struct color_converter *converter = impl_color_converter_from_IMFTransform(iface); -+ UINT64 framesize; -+ GUID subtype; - -- return E_NOTIMPL; -+ TRACE("%p %u %p.\n", iface, id, info); -+ -+ if (id != 0) -+ return MF_E_INVALIDSTREAMNUMBER; -+ -+ info->dwFlags = MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE | MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES | MFT_OUTPUT_STREAM_WHOLE_SAMPLES | MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER; -+ info->cbAlignment = 0; -+ info->cbSize = 0; -+ -+ EnterCriticalSection(&converter->cs); -+ -+ if (converter->output_type) -+ { -+ if (SUCCEEDED(IMFMediaType_GetGUID(converter->output_type, &MF_MT_SUBTYPE, &subtype)) && -+ SUCCEEDED(IMFMediaType_GetUINT64(converter->output_type, &MF_MT_FRAME_SIZE, &framesize))) -+ { -+ MFCalculateImageSize(&subtype, framesize >> 32, (UINT32) framesize, &info->cbSize); -+ } -+ -+ if (!info->cbSize) -+ WARN("Failed to get desired output buffer size, the non-provided sample path will likely break\n"); -+ } -+ -+ LeaveCriticalSection(&converter->cs); -+ -+ return S_OK; - } - - static HRESULT WINAPI color_converter_GetAttributes(IMFTransform *iface, IMFAttributes **attributes) --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0037-winegstreamer-Handle-flush-command-in-audio-converst.patch b/patches/mfplat-streaming-support/0037-winegstreamer-Handle-flush-command-in-audio-converst.patch deleted file mode 100644 index c64a53bb..00000000 --- a/patches/mfplat-streaming-support/0037-winegstreamer-Handle-flush-command-in-audio-converst.patch +++ /dev/null @@ -1,26 +0,0 @@ -From 7dad9c2c92351194857e9722a0dd72d280abac0f Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Thu, 18 Mar 2021 14:53:49 -0400 -Subject: [PATCH 37/88] winegstreamer: Handle flush command in audio - converstion transform. - -Signed-off-by: Derek Lesho ---- - dlls/winegstreamer/audioconvert.c | 1 + - 1 file changed, 1 insertion(+) - -diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c -index a4258c6aecd..afa6bd682a6 100644 ---- a/dlls/winegstreamer/audioconvert.c -+++ b/dlls/winegstreamer/audioconvert.c -@@ -563,6 +563,7 @@ static HRESULT WINAPI audio_converter_ProcessMessage(IMFTransform *iface, MFT_ME - - switch(message) - { -+ case MFT_MESSAGE_COMMAND_FLUSH: - case MFT_MESSAGE_NOTIFY_BEGIN_STREAMING: - return S_OK; - default: --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0039-winegstreamer-Implement-IMFTransform-GetOutputCurren.patch b/patches/mfplat-streaming-support/0039-winegstreamer-Implement-IMFTransform-GetOutputCurren.patch deleted file mode 100644 index 172aaca0..00000000 --- a/patches/mfplat-streaming-support/0039-winegstreamer-Implement-IMFTransform-GetOutputCurren.patch +++ /dev/null @@ -1,54 +0,0 @@ -From fc96686a97ff86e036a4324299392c66250a77fc Mon Sep 17 00:00:00 2001 -From: Andrew Eikum -Date: Mon, 18 Oct 2021 12:29:34 -0500 -Subject: [PATCH 39/88] winegstreamer: Implement - IMFTransform::GetOutputCurrentType in colorconvert - -CW-Bug-Id: #19465 ---- - dlls/winegstreamer/colorconvert.c | 28 ++++++++++++++++++++++++++-- - 1 file changed, 26 insertions(+), 2 deletions(-) - -diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c -index db4ca4e3fbe..baf429d42f9 100644 ---- a/dlls/winegstreamer/colorconvert.c -+++ b/dlls/winegstreamer/colorconvert.c -@@ -493,9 +493,33 @@ static HRESULT WINAPI color_converter_GetInputCurrentType(IMFTransform *iface, D - - static HRESULT WINAPI color_converter_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) - { -- FIXME("%p, %u, %p.\n", iface, id, type); -+ struct color_converter *converter = impl_color_converter_from_IMFTransform(iface); -+ IMFMediaType *ret; -+ HRESULT hr; - -- return E_NOTIMPL; -+ TRACE("%p, %u, %p.\n", converter, id, type); -+ -+ if (id != 0) -+ return MF_E_INVALIDSTREAMNUMBER; -+ -+ if (FAILED(hr = MFCreateMediaType(&ret))) -+ return hr; -+ -+ EnterCriticalSection(&converter->cs); -+ -+ if (converter->output_type) -+ hr = IMFMediaType_CopyAllItems(converter->output_type, (IMFAttributes *)ret); -+ else -+ hr = MF_E_TRANSFORM_TYPE_NOT_SET; -+ -+ LeaveCriticalSection(&converter->cs); -+ -+ if (SUCCEEDED(hr)) -+ *type = ret; -+ else -+ IMFMediaType_Release(ret); -+ -+ return hr; - } - - static HRESULT WINAPI color_converter_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags) --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0040-winegstreamer-Implement-stream-draining-support.patch b/patches/mfplat-streaming-support/0040-winegstreamer-Implement-stream-draining-support.patch deleted file mode 100644 index 966ffdb9..00000000 --- a/patches/mfplat-streaming-support/0040-winegstreamer-Implement-stream-draining-support.patch +++ /dev/null @@ -1,178 +0,0 @@ -From 5f724ac4f148607141e93868ba97edb4c0135cbd Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Tue, 14 Dec 2021 22:31:29 +0100 -Subject: [PATCH 40/88] winegstreamer: Implement stream draining support. - ---- - dlls/winegstreamer/gst_private.h | 1 + - dlls/winegstreamer/main.c | 5 +++ - dlls/winegstreamer/unixlib.h | 2 + - dlls/winegstreamer/wg_parser.c | 70 +++++++++++++++++++++++++++++++- - 4 files changed, 77 insertions(+), 1 deletion(-) - -diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h -index d3271518f8f..6149ae5959c 100644 ---- a/dlls/winegstreamer/gst_private.h -+++ b/dlls/winegstreamer/gst_private.h -@@ -95,6 +95,7 @@ uint64_t wg_parser_stream_get_duration(struct wg_parser_stream *stream); - /* start_pos and stop_pos are in 100-nanosecond units. */ - void wg_parser_stream_seek(struct wg_parser_stream *stream, double rate, - uint64_t start_pos, uint64_t stop_pos, DWORD start_flags, DWORD stop_flags); -+bool wg_parser_stream_drain(struct wg_parser_stream *stream); - - unsigned int wg_format_get_max_size(const struct wg_format *format); - -diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c -index 8f487655748..66b7a1195ee 100644 ---- a/dlls/winegstreamer/main.c -+++ b/dlls/winegstreamer/main.c -@@ -254,6 +254,11 @@ void wg_parser_stream_seek(struct wg_parser_stream *stream, double rate, - __wine_unix_call(unix_handle, unix_wg_parser_stream_seek, ¶ms); - } - -+bool wg_parser_stream_drain(struct wg_parser_stream *stream) -+{ -+ return !__wine_unix_call(unix_handle, unix_wg_parser_stream_drain, stream); -+} -+ - BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved) - { - if (reason == DLL_PROCESS_ATTACH) -diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h -index d9c675ea873..fc9d0c3c80d 100644 ---- a/dlls/winegstreamer/unixlib.h -+++ b/dlls/winegstreamer/unixlib.h -@@ -271,6 +271,8 @@ enum unix_funcs - - unix_wg_parser_stream_get_duration, - unix_wg_parser_stream_seek, -+ -+ unix_wg_parser_stream_drain, - }; - - #endif /* __WINE_WINEGSTREAMER_UNIXLIB_H */ -diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index 1d34437318e..f70c1a449c7 100644 ---- a/dlls/winegstreamer/wg_parser.c -+++ b/dlls/winegstreamer/wg_parser.c -@@ -87,7 +87,7 @@ struct wg_parser - GstFlowReturn ret; - } read_request; - -- bool flushing, sink_connected; -+ bool flushing, sink_connected, draining; - - bool unlimited_buffering; - }; -@@ -769,6 +769,16 @@ static NTSTATUS wg_parser_stream_get_event(void *args) - - *params->event = stream->event; - -+ /* Set to ensure that drain isn't called on an EOS stream, causing a lock-up -+ due to pull_data never being called again */ -+ if (stream->event.type == WG_PARSER_EVENT_EOS) -+ stream->eos = true; -+ -+ /* Set to ensure that drain isn't called on an EOS stream, causing a lock-up -+ due to pull_data never being called again */ -+ if (stream->event.type == WG_PARSER_EVENT_EOS) -+ stream->eos = true; -+ - if (stream->event.type != WG_PARSER_EVENT_BUFFER) - { - stream->event.type = WG_PARSER_EVENT_NONE; -@@ -859,6 +869,44 @@ static NTSTATUS wg_parser_stream_seek(void *args) - return S_OK; - } - -+static NTSTATUS wg_parser_stream_drain(void *args) -+{ -+ struct wg_parser_stream *stream = args; -+ struct wg_parser *parser = stream->parser; -+ bool ret; -+ -+ pthread_mutex_lock(&parser->mutex); -+ -+ /* Sanity check making sure caller didn't try to drain an already-EOS or unselected stream. -+ There's no reason for a caller to do this, but it could be an accident in which case we -+ should indicate that the stream is drained instead of locking-up. */ -+ if (!stream->enabled || stream->eos) -+ { -+ pthread_mutex_unlock(&parser->mutex); -+ return true; -+ } -+ -+ parser->draining = true; -+ pthread_cond_signal(&parser->read_done_cond); -+ -+ /* We must wait for either an event to occur or the drain to complete. -+ Since drains are blocking, we assign this responsibility to the thread -+ pulling data, as the pipeline will not need to pull more data until -+ the drain completes. If one input buffer yields more than one output -+ buffer, the chain callback blocks on the wg_parser_stream_buffer_release -+ for the first buffer, which would never be called if the drain function -+ hadn't completed. */ -+ while (!parser->flushing && parser->draining && stream->event.type == WG_PARSER_EVENT_NONE) -+ pthread_cond_wait(&stream->event_cond, &parser->mutex); -+ -+ ret = stream->event.type == WG_PARSER_EVENT_NONE; -+ parser->draining = false; -+ -+ pthread_mutex_unlock(&stream->parser->mutex); -+ -+ return ret; -+} -+ - static NTSTATUS wg_parser_stream_notify_qos(void *args) - { - const struct wg_parser_stream_notify_qos_params *params = args; -@@ -1431,6 +1479,7 @@ static GstFlowReturn src_getrange_cb(GstPad *pad, GstObject *parent, - { - struct wg_parser *parser = gst_pad_get_element_private(pad); - GstFlowReturn ret; -+ unsigned int i; - - GST_LOG("pad %p, offset %" G_GINT64_MODIFIER "u, size %u, buffer %p.", pad, offset, size, *buffer); - -@@ -1452,6 +1501,14 @@ static GstFlowReturn src_getrange_cb(GstPad *pad, GstObject *parent, - - pthread_mutex_lock(&parser->mutex); - -+ if (parser->draining) -+ { -+ gst_pad_peer_query(parser->my_src, gst_query_new_drain()); -+ parser->draining = false; -+ for (i = 0; i < parser->stream_count; i++) -+ pthread_cond_signal(&parser->streams[i]->event_cond); -+ } -+ - assert(!parser->read_request.size); - parser->read_request.buffer = *buffer; - parser->read_request.offset = offset; -@@ -1464,7 +1521,16 @@ static GstFlowReturn src_getrange_cb(GstPad *pad, GstObject *parent, - * read_thread() not running. */ - - while (!parser->read_request.done) -+ { - pthread_cond_wait(&parser->read_done_cond, &parser->mutex); -+ if (parser->draining) -+ { -+ gst_pad_peer_query(parser->my_src, gst_query_new_drain()); -+ parser->draining = false; -+ for (i = 0; i < parser->stream_count; i++) -+ pthread_cond_signal(&parser->streams[i]->event_cond); -+ } -+ } - - *buffer = parser->read_request.buffer; - ret = parser->read_request.ret; -@@ -2208,4 +2274,6 @@ const unixlib_entry_t __wine_unix_call_funcs[] = - - X(wg_parser_stream_get_duration), - X(wg_parser_stream_seek), -+ -+ X(wg_parser_stream_drain), - }; --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0045-winegstreamer-Implement-unseekable-stream-support.patch b/patches/mfplat-streaming-support/0045-winegstreamer-Implement-unseekable-stream-support.patch deleted file mode 100644 index 65c61c08..00000000 --- a/patches/mfplat-streaming-support/0045-winegstreamer-Implement-unseekable-stream-support.patch +++ /dev/null @@ -1,436 +0,0 @@ -From 7a63ae845a7d1d630ae838ddebc25a20c54df889 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Wed, 15 Dec 2021 10:25:48 +0100 -Subject: [PATCH 45/88] winegstreamer: Implement unseekable stream support. - ---- - dlls/winegstreamer/gst_private.h | 2 + - dlls/winegstreamer/main.c | 14 +++ - dlls/winegstreamer/unixlib.h | 9 ++ - dlls/winegstreamer/wg_parser.c | 197 ++++++++++++++++++++++++++++--- - 4 files changed, 203 insertions(+), 19 deletions(-) - -diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h -index c156d87450c..6e7c53782c8 100644 ---- a/dlls/winegstreamer/gst_private.h -+++ b/dlls/winegstreamer/gst_private.h -@@ -68,6 +68,8 @@ struct wg_parser *wg_parser_create(enum wg_parser_type type, bool unlimited_buff - void wg_parser_destroy(struct wg_parser *parser); - - HRESULT wg_parser_connect(struct wg_parser *parser, uint64_t file_size); -+HRESULT wg_parser_connect_unseekable(struct wg_parser *parser, const struct wg_format *in_format, -+ uint32_t stream_count, const struct wg_format *out_formats); - void wg_parser_disconnect(struct wg_parser *parser); - - void wg_parser_begin_flush(struct wg_parser *parser); -diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c -index db05594f464..316becdbc97 100644 ---- a/dlls/winegstreamer/main.c -+++ b/dlls/winegstreamer/main.c -@@ -91,6 +91,20 @@ HRESULT wg_parser_connect(struct wg_parser *parser, uint64_t file_size) - return __wine_unix_call(unix_handle, unix_wg_parser_connect, ¶ms); - } - -+HRESULT wg_parser_connect_unseekable(struct wg_parser *parser, const struct wg_format *in_format, -+ uint32_t stream_count, const struct wg_format *out_formats) -+{ -+ struct wg_parser_connect_unseekable_params params = -+ { -+ .parser = parser, -+ .in_format = in_format, -+ .stream_count = stream_count, -+ .out_formats = out_formats, -+ }; -+ -+ return __wine_unix_call(unix_handle, unix_wg_parser_connect_unseekable, ¶ms); -+} -+ - void wg_parser_disconnect(struct wg_parser *parser) - { - __wine_unix_call(unix_handle, unix_wg_parser_disconnect, parser); -diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h -index f20ee5bb52f..e5d87716734 100644 ---- a/dlls/winegstreamer/unixlib.h -+++ b/dlls/winegstreamer/unixlib.h -@@ -175,6 +175,14 @@ struct wg_parser_connect_params - UINT64 file_size; - }; - -+struct wg_parser_connect_unseekable_params -+{ -+ struct wg_parser *parser; -+ const struct wg_format *in_format; -+ UINT32 stream_count; -+ const struct wg_format *out_formats; -+}; -+ - struct wg_parser_get_next_read_offset_params - { - struct wg_parser *parser; -@@ -258,6 +266,7 @@ enum unix_funcs - unix_wg_parser_destroy, - - unix_wg_parser_connect, -+ unix_wg_parser_connect_unseekable, - unix_wg_parser_disconnect, - - unix_wg_parser_begin_flush, -diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index 0b67a6836c4..ab850b899f3 100644 ---- a/dlls/winegstreamer/wg_parser.c -+++ b/dlls/winegstreamer/wg_parser.c -@@ -61,7 +61,7 @@ struct wg_parser - init_gst_cb init_gst; - - struct wg_parser_stream **streams; -- unsigned int stream_count; -+ unsigned int stream_count, expected_stream_count; - - GstElement *container, *decodebin; - GstBus *bus; -@@ -75,7 +75,7 @@ struct wg_parser - pthread_mutex_t mutex; - - pthread_cond_t init_cond; -- bool no_more_pads, has_duration, error, pull_mode; -+ bool no_more_pads, has_duration, error, pull_mode, seekable; - - pthread_cond_t read_cond, read_done_cond; - struct -@@ -90,6 +90,7 @@ struct wg_parser - bool flushing, sink_connected, draining; - - bool unlimited_buffering; -+ struct wg_format input_format; - }; - - struct wg_parser_stream -@@ -600,6 +601,9 @@ static NTSTATUS wg_parser_begin_flush(void *args) - struct wg_parser *parser = args; - unsigned int i; - -+ if (!parser->seekable) -+ return S_OK; -+ - pthread_mutex_lock(&parser->mutex); - parser->flushing = true; - pthread_mutex_unlock(&parser->mutex); -@@ -617,6 +621,9 @@ static NTSTATUS wg_parser_end_flush(void *args) - { - struct wg_parser *parser = args; - -+ if (!parser->seekable) -+ return S_OK; -+ - pthread_mutex_lock(&parser->mutex); - parser->flushing = false; - pthread_mutex_unlock(&parser->mutex); -@@ -711,7 +718,9 @@ static NTSTATUS wg_parser_stream_get_preferred_format(void *args) - { - const struct wg_parser_stream_get_preferred_format_params *params = args; - -- *params->format = params->stream->preferred_format; -+ if (params->stream->has_caps) -+ *params->format = params->stream->preferred_format; -+ - return S_OK; - } - -@@ -721,6 +730,9 @@ static NTSTATUS wg_parser_stream_enable(void *args) - struct wg_parser_stream *stream = params->stream; - const struct wg_format *format = params->format; - -+ if (!stream->parser->seekable) -+ return S_OK; -+ - stream->current_format = *format; - stream->enabled = true; - -@@ -867,6 +879,9 @@ static NTSTATUS wg_parser_stream_seek(void *args) - DWORD stop_flags = params->stop_flags; - GstSeekFlags flags = 0; - -+ if (!params->stream->parser->seekable) -+ return E_FAIL; -+ - if (start_flags & AM_SEEKING_SeekToKeyFrame) - flags |= GST_SEEK_FLAG_KEY_UNIT; - if (start_flags & AM_SEEKING_Segment) -@@ -1246,14 +1261,27 @@ static GstElement *create_element(const char *name, const char *plugin_set) - static struct wg_parser_stream *create_stream(struct wg_parser *parser) - { - struct wg_parser_stream *stream, **new_array; -+ unsigned int i; - char pad_name[19]; - -- if (!(new_array = realloc(parser->streams, (parser->stream_count + 1) * sizeof(*parser->streams)))) -- return NULL; -- parser->streams = new_array; -+ for (i = 0; i < parser->expected_stream_count; i++) -+ { -+ if (!parser->streams[i]->parser) -+ { -+ stream = parser->streams[i]; -+ break; -+ } -+ } - -- if (!(stream = calloc(1, sizeof(*stream)))) -- return NULL; -+ if (i == parser->expected_stream_count) -+ { -+ if (!(new_array = realloc(parser->streams, (parser->stream_count + 1) * sizeof(*parser->streams)))) -+ return NULL; -+ parser->streams = new_array; -+ -+ if (!(stream = calloc(1, sizeof(*stream)))) -+ return NULL; -+ } - - gst_segment_init(&stream->segment, GST_FORMAT_UNDEFINED); - -@@ -1575,7 +1603,7 @@ static gboolean src_query_cb(GstPad *pad, GstObject *parent, GstQuery *query) - gst_query_set_duration(query, GST_FORMAT_PERCENT, GST_FORMAT_PERCENT_MAX); - return TRUE; - } -- else if (format == GST_FORMAT_BYTES) -+ else if (format == GST_FORMAT_BYTES && parser->seekable) - { - gst_query_set_duration(query, GST_FORMAT_BYTES, parser->file_size); - return TRUE; -@@ -1589,15 +1617,42 @@ static gboolean src_query_cb(GstPad *pad, GstObject *parent, GstQuery *query) - GST_WARNING("Cannot seek using format \"%s\".", gst_format_get_name(format)); - return FALSE; - } -+ if (!parser->seekable) -+ return FALSE; - gst_query_set_seeking(query, GST_FORMAT_BYTES, 1, 0, parser->file_size); - return TRUE; - - case GST_QUERY_SCHEDULING: -- gst_query_set_scheduling(query, GST_SCHEDULING_FLAG_SEEKABLE, 1, -1, 0); -+ gst_query_set_scheduling(query, parser->seekable ? GST_SCHEDULING_FLAG_SEEKABLE : GST_SCHEDULING_FLAG_SEQUENTIAL, 1, -1, 0); - gst_query_add_scheduling_mode(query, GST_PAD_MODE_PUSH); - gst_query_add_scheduling_mode(query, GST_PAD_MODE_PULL); - return TRUE; - -+ case GST_QUERY_CAPS: -+ { -+ GstCaps *caps, *filter, *temp; -+ -+ gst_query_parse_caps(query, &filter); -+ -+ if (parser->input_format.major_type) -+ caps = wg_format_to_caps(&parser->input_format); -+ else -+ caps = gst_caps_new_any(); -+ if (!caps) -+ return FALSE; -+ -+ if (filter) -+ { -+ temp = gst_caps_intersect(caps, filter); -+ gst_caps_unref(caps); -+ caps = temp; -+ } -+ -+ gst_query_set_caps_result(query, caps); -+ gst_caps_unref(caps); -+ return TRUE; -+ } -+ - default: - GST_WARNING("Unhandled query type %s.", GST_QUERY_TYPE_NAME(query)); - return FALSE; -@@ -1607,16 +1662,31 @@ static gboolean src_query_cb(GstPad *pad, GstObject *parent, GstQuery *query) - static void *push_data(void *arg) - { - struct wg_parser *parser = arg; -+ ULONG alloc_size = 16384; -+ GstCaps *caps = NULL; - GstSegment *segment; - GstBuffer *buffer; -+ unsigned int i; - guint max_size; - - GST_DEBUG("Starting push thread."); - -+ if (parser->input_format.major_type) -+ caps = wg_format_to_caps(&parser->input_format); -+ -+ if (parser->input_format.major_type == WG_MAJOR_TYPE_VIDEO) -+ { -+ GstVideoInfo info; -+ gst_video_info_from_caps(&info, caps); -+ alloc_size = info.size; -+ } -+ - max_size = parser->stop_offset ? parser->stop_offset : parser->file_size; - - gst_pad_push_event(parser->my_src, gst_event_new_stream_start("wg_stream")); - -+ if (caps) gst_pad_push_event(parser->my_src, gst_event_new_caps(caps)); -+ - segment = gst_segment_new(); - gst_segment_init(segment, GST_FORMAT_BYTES); - gst_pad_push_event(parser->my_src, gst_event_new_segment(segment)); -@@ -1626,13 +1696,47 @@ static void *push_data(void *arg) - ULONG size; - int ret; - -- if (parser->next_offset >= max_size) -+ if (parser->seekable && parser->next_offset >= max_size) - break; -- size = min(16384, max_size - parser->next_offset); -+ size = parser->seekable ? min(alloc_size, max_size - parser->next_offset) : alloc_size; - - buffer = NULL; -- if ((ret = src_getrange_cb(parser->my_src, NULL, parser->next_offset, size, &buffer)) < 0) -+ if ((ret = src_getrange_cb(parser->my_src, NULL, parser->next_offset, size, &buffer) < 0)) - { -+ /* When we are in unseekable push mode, the pushing pad is responsible for handling flushing. */ -+ if (!parser->seekable && ret == GST_FLOW_FLUSHING) -+ { -+ gst_pad_push_event(parser->my_src, gst_event_new_seek(1.0f, -+ GST_FORMAT_BYTES, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_NONE, 0, GST_SEEK_TYPE_NONE, 0)); -+ continue; -+ } -+ -+ if (!parser->seekable && ret == GST_FLOW_EOS) -+ { -+ gst_pad_push_event(parser->my_src, gst_event_new_eos()); -+ pthread_mutex_lock(&parser->mutex); -+ for (i = 0; i < parser->stream_count; i++) -+ { -+ if (!parser->streams[i]->enabled) -+ continue; -+ while (!parser->streams[i]->flushing && !parser->streams[i]->eos) -+ pthread_cond_wait(&parser->streams[i]->event_empty_cond, &parser->mutex); -+ parser->streams[i]->eos = false; -+ } -+ -+ if (parser->flushing) -+ { -+ pthread_mutex_unlock(&parser->mutex); -+ continue; -+ } -+ pthread_mutex_unlock(&parser->mutex); -+ -+ segment = gst_segment_new(); -+ gst_segment_init(segment, GST_FORMAT_BYTES); -+ gst_pad_push_event(parser->my_src, gst_event_new_segment(segment)); -+ continue; -+ } -+ - GST_ERROR("Failed to read data, ret %s.", gst_flow_get_name(ret)); - break; - } -@@ -1827,16 +1931,11 @@ static gboolean src_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) - return ret; - } - --static NTSTATUS wg_parser_connect(void *args) -+static HRESULT wg_parser_connect_inner(struct wg_parser *parser) - { - GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE("wine_src", - GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY); -- const struct wg_parser_connect_params *params = args; -- struct wg_parser *parser = params->parser; -- unsigned int i; -- int ret; - -- parser->file_size = params->file_size; - parser->sink_connected = true; - - if (!parser->bus) -@@ -1859,6 +1958,23 @@ static NTSTATUS wg_parser_connect(void *args) - parser->next_pull_offset = 0; - parser->error = false; - -+ return S_OK; -+} -+ -+static NTSTATUS wg_parser_connect(void *args) -+{ -+ const struct wg_parser_connect_params *params = args; -+ struct wg_parser *parser = params->parser; -+ unsigned int i; -+ HRESULT hr; -+ int ret; -+ -+ parser->seekable = true; -+ parser->file_size = params->file_size; -+ -+ if ((hr = wg_parser_connect_inner(parser))) -+ return hr; -+ - if (!parser->init_gst(parser)) - goto out; - -@@ -1988,6 +2104,45 @@ out: - return E_FAIL; - } - -+static NTSTATUS wg_parser_connect_unseekable(void *args) -+{ -+ const struct wg_parser_connect_unseekable_params *params = args; -+ const struct wg_format *out_formats = params->out_formats; -+ const struct wg_format *in_format = params->in_format; -+ uint32_t stream_count = params->stream_count; -+ struct wg_parser *parser = params->parser; -+ unsigned int i; -+ HRESULT hr; -+ -+ parser->seekable = false; -+ parser->flushing = false; -+ /* since typefind is not available here, we must have an input_format */ -+ parser->input_format = *in_format; -+ -+ if ((hr = wg_parser_connect_inner(parser))) -+ return hr; -+ -+ parser->stop_offset = -1; -+ -+ parser->expected_stream_count = stream_count; -+ parser->streams = calloc(stream_count, sizeof(*parser->streams)); -+ -+ for (i = 0; i < stream_count; i++) -+ { -+ parser->streams[i] = calloc(1, sizeof(*parser->streams[i])); -+ parser->streams[i]->current_format = out_formats[i]; -+ parser->streams[i]->enabled = true; -+ } -+ -+ if (!parser->init_gst(parser)) -+ return E_FAIL; -+ -+ if (parser->stream_count < parser->expected_stream_count) -+ return E_FAIL; -+ -+ return S_OK; -+} -+ - static NTSTATUS wg_parser_disconnect(void *args) - { - struct wg_parser *parser = args; -@@ -2037,6 +2192,9 @@ static BOOL decodebin_parser_init_gst(struct wg_parser *parser) - if (!(element = create_element("decodebin", "base"))) - return FALSE; - -+ if (parser->input_format.major_type) -+ g_object_set(G_OBJECT(element), "sink-caps", wg_format_to_caps(&parser->input_format), NULL); -+ - gst_bin_add(GST_BIN(parser->container), element); - parser->decodebin = element; - -@@ -2262,6 +2420,7 @@ const unixlib_entry_t __wine_unix_call_funcs[] = - X(wg_parser_destroy), - - X(wg_parser_connect), -+ X(wg_parser_connect_unseekable), - X(wg_parser_disconnect), - - X(wg_parser_begin_flush), --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0046-winegstreamer-Implement-Process-Input-Output-for-dec.patch b/patches/mfplat-streaming-support/0046-winegstreamer-Implement-Process-Input-Output-for-dec.patch deleted file mode 100644 index b30467ad..00000000 --- a/patches/mfplat-streaming-support/0046-winegstreamer-Implement-Process-Input-Output-for-dec.patch +++ /dev/null @@ -1,676 +0,0 @@ -From 4518afa81504bbbd86fd3ee62683169730255277 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Fri, 19 Mar 2021 16:53:02 -0400 -Subject: [PATCH 46/88] winegstreamer: Implement ::Process(Input/Output) for - decoder transform. - ---- - dlls/winegstreamer/decode_transform.c | 542 +++++++++++++++++++++++++- - dlls/winegstreamer/wg_parser.c | 4 + - 2 files changed, 540 insertions(+), 6 deletions(-) - -diff --git a/dlls/winegstreamer/decode_transform.c b/dlls/winegstreamer/decode_transform.c -index 4967fc49012..c2b70c10f41 100644 ---- a/dlls/winegstreamer/decode_transform.c -+++ b/dlls/winegstreamer/decode_transform.c -@@ -61,14 +61,47 @@ static struct decoder_desc - } - }; - -+struct pipeline_event -+{ -+ enum -+ { -+ PIPELINE_EVENT_NONE, -+ PIPELINE_EVENT_PARSER_STARTED, -+ PIPELINE_EVENT_READ_REQUEST, -+ } type; -+ union -+ { -+ struct -+ { -+ struct wg_parser_stream *stream; -+ } parser_started; -+ } u; -+}; -+ - struct mf_decoder - { - IMFTransform IMFTransform_iface; - LONG refcount; - enum decoder_type type; - IMFMediaType *input_type, *output_type; -- CRITICAL_SECTION cs; -- BOOL video; -+ CRITICAL_SECTION cs, help_cs, event_cs; -+ CONDITION_VARIABLE help_cv, event_cv; -+ BOOL flushing, draining, eos, helper_thread_shutdown, video; -+ HANDLE helper_thread, read_thread; -+ uint64_t offset_tracker; -+ struct wg_parser *wg_parser; -+ struct wg_parser_stream *wg_stream; -+ -+ struct -+ { -+ enum -+ { -+ HELP_REQ_NONE, -+ HELP_REQ_START_PARSER, -+ } type; -+ } help_request; -+ -+ struct pipeline_event event; - }; - - static struct mf_decoder *impl_mf_decoder_from_IMFTransform(IMFTransform *iface) -@@ -124,7 +157,35 @@ static ULONG WINAPI mf_decoder_Release(IMFTransform *iface) - decoder->output_type = NULL; - } - -+ if (decoder->wg_parser) -+ { -+ /* NULL wg_parser is possible if the wg_parser creation failed. */ -+ -+ if (decoder->wg_stream) -+ wg_parser_disconnect(decoder->wg_parser); -+ -+ EnterCriticalSection(&decoder->event_cs); -+ decoder->helper_thread_shutdown = TRUE; -+ WakeAllConditionVariable(&decoder->event_cv); -+ LeaveCriticalSection(&decoder->event_cs); -+ -+ EnterCriticalSection(&decoder->help_cs); -+ WakeAllConditionVariable(&decoder->help_cv); -+ LeaveCriticalSection(&decoder->help_cs); -+ -+ if (WaitForSingleObject(decoder->helper_thread, 10000) != WAIT_OBJECT_0) -+ FIXME("Failed waiting for helper thread to terminate.\n"); -+ CloseHandle(decoder->helper_thread); -+ if (WaitForSingleObject(decoder->read_thread, 10000) != WAIT_OBJECT_0) -+ FIXME("Failed waiting for read thread to terminate.\n"); -+ CloseHandle(decoder->read_thread); -+ -+ wg_parser_destroy(decoder->wg_parser); -+ } -+ - DeleteCriticalSection(&decoder->cs); -+ DeleteCriticalSection(&decoder->help_cs); -+ DeleteCriticalSection(&decoder->event_cs); - - heap_free(decoder); - } -@@ -351,6 +412,12 @@ static HRESULT WINAPI mf_decoder_SetInputType(IMFTransform *iface, DWORD id, IMF - - EnterCriticalSection(&decoder->cs); - -+ if (decoder->wg_stream) -+ { -+ decoder->wg_stream = NULL; -+ wg_parser_disconnect(decoder->wg_parser); -+ } -+ - if (decoder->input_type) - { - IMFMediaType_Release(decoder->input_type); -@@ -389,6 +456,12 @@ static HRESULT WINAPI mf_decoder_SetInputType(IMFTransform *iface, DWORD id, IMF - - hr = S_OK; - -+ if (decoder->wg_stream) -+ { -+ decoder->wg_stream = NULL; -+ wg_parser_disconnect(decoder->wg_parser); -+ } -+ - if (!decoder->input_type) - hr = MFCreateMediaType(&decoder->input_type); - -@@ -398,6 +471,16 @@ static HRESULT WINAPI mf_decoder_SetInputType(IMFTransform *iface, DWORD id, IMF - decoder->input_type = NULL; - } - -+ if (decoder->input_type && decoder->output_type) -+ { -+ EnterCriticalSection(&decoder->help_cs); -+ while(decoder->help_request.type != HELP_REQ_NONE) -+ SleepConditionVariableCS(&decoder->help_cv, &decoder->help_cs, INFINITE); -+ decoder->help_request.type = HELP_REQ_START_PARSER; -+ LeaveCriticalSection(&decoder->help_cs); -+ WakeAllConditionVariable(&decoder->help_cv); -+ } -+ - LeaveCriticalSection(&decoder->cs); - return hr; - } -@@ -422,6 +505,12 @@ static HRESULT WINAPI mf_decoder_SetOutputType(IMFTransform *iface, DWORD id, IM - - EnterCriticalSection(&decoder->cs); - -+ if (decoder->wg_stream) -+ { -+ decoder->wg_stream = NULL; -+ wg_parser_disconnect(decoder->wg_parser); -+ } -+ - if (decoder->output_type) - { - IMFMediaType_Release(decoder->output_type); -@@ -460,6 +549,12 @@ static HRESULT WINAPI mf_decoder_SetOutputType(IMFTransform *iface, DWORD id, IM - - hr = S_OK; - -+ if (decoder->wg_stream) -+ { -+ decoder->wg_stream = NULL; -+ wg_parser_disconnect(decoder->wg_parser); -+ } -+ - if (!decoder->output_type) - hr = MFCreateMediaType(&decoder->output_type); - -@@ -469,6 +564,16 @@ static HRESULT WINAPI mf_decoder_SetOutputType(IMFTransform *iface, DWORD id, IM - decoder->output_type = NULL; - } - -+ if (decoder->input_type && decoder->output_type) -+ { -+ EnterCriticalSection(&decoder->help_cs); -+ while(decoder->help_request.type != HELP_REQ_NONE) -+ SleepConditionVariableCS(&decoder->help_cv, &decoder->help_cs, INFINITE); -+ decoder->help_request.type = HELP_REQ_START_PARSER; -+ LeaveCriticalSection(&decoder->help_cs); -+ WakeAllConditionVariable(&decoder->help_cv); -+ } -+ - LeaveCriticalSection(&decoder->cs); - return hr; - } -@@ -515,6 +620,117 @@ static HRESULT WINAPI mf_decoder_ProcessEvent(IMFTransform *iface, DWORD id, IMF - return E_NOTIMPL; - } - -+static DWORD CALLBACK helper_thread_func(PVOID ctx) -+{ -+ struct mf_decoder *decoder = (struct mf_decoder *)ctx; -+ -+ for(;;) -+ { -+ EnterCriticalSection(&decoder->help_cs); -+ -+ while(!decoder->helper_thread_shutdown && decoder->help_request.type == HELP_REQ_NONE) -+ SleepConditionVariableCS(&decoder->help_cv, &decoder->help_cs, INFINITE); -+ if (decoder->helper_thread_shutdown) -+ { -+ LeaveCriticalSection(&decoder->help_cs); -+ return 0; -+ } -+ -+ switch(decoder->help_request.type) -+ { -+ case HELP_REQ_START_PARSER: -+ { -+ struct wg_format input_format, output_format; -+ -+ decoder->help_request.type = HELP_REQ_NONE; -+ LeaveCriticalSection(&decoder->help_cs); -+ -+ mf_media_type_to_wg_format(decoder->input_type, &input_format); -+ mf_media_type_to_wg_format(decoder->output_type, &output_format); -+ -+ wg_parser_connect_unseekable(decoder->wg_parser, &input_format, 1, &output_format); -+ -+ EnterCriticalSection(&decoder->event_cs); -+ while (!decoder->helper_thread_shutdown && decoder->event.type != PIPELINE_EVENT_NONE) -+ SleepConditionVariableCS(&decoder->event_cv, &decoder->event_cs, INFINITE); -+ -+ if (decoder->helper_thread_shutdown) -+ { -+ LeaveCriticalSection(&decoder->event_cs); -+ return 0; -+ } -+ -+ decoder->event.type = PIPELINE_EVENT_PARSER_STARTED; -+ decoder->event.u.parser_started.stream = wg_parser_get_stream(decoder->wg_parser, 0); -+ -+ LeaveCriticalSection(&decoder->event_cs); -+ WakeAllConditionVariable(&decoder->event_cv); -+ -+ break; -+ } -+ default: -+ assert(0); -+ } -+ } -+} -+ -+/* We use a separate thread to wait for reads, as we may want to wait to WAIT_ANY -+ on a read and another event. */ -+static DWORD CALLBACK read_thread_func(PVOID ctx) -+{ -+ struct mf_decoder *decoder = (struct mf_decoder *)ctx; -+ uint64_t offset; -+ uint32_t size; -+ -+ for (;;) -+ { -+ if (decoder->helper_thread_shutdown) -+ break; -+ -+ if (!wg_parser_get_next_read_offset(decoder->wg_parser, &offset, &size)) -+ continue; -+ -+ EnterCriticalSection(&decoder->event_cs); -+ while (!decoder->helper_thread_shutdown && decoder->event.type != PIPELINE_EVENT_NONE) -+ SleepConditionVariableCS(&decoder->event_cv, &decoder->event_cs, INFINITE); -+ -+ if (decoder->helper_thread_shutdown) -+ { -+ LeaveCriticalSection(&decoder->event_cs); -+ break; -+ } -+ -+ decoder->event.type = PIPELINE_EVENT_READ_REQUEST; -+ WakeAllConditionVariable(&decoder->event_cv); -+ while (!decoder->helper_thread_shutdown && decoder->event.type == PIPELINE_EVENT_READ_REQUEST) -+ SleepConditionVariableCS(&decoder->event_cv, &decoder->event_cs, INFINITE); -+ LeaveCriticalSection(&decoder->event_cs); -+ } -+ -+ return 0; -+} -+ -+static struct pipeline_event get_pipeline_event(struct mf_decoder *decoder) -+{ -+ struct pipeline_event ret; -+ -+ EnterCriticalSection(&decoder->event_cs); -+ while(decoder->event.type == PIPELINE_EVENT_NONE) -+ SleepConditionVariableCS(&decoder->event_cv, &decoder->event_cs, INFINITE); -+ -+ ret = decoder->event; -+ -+ if (ret.type != PIPELINE_EVENT_READ_REQUEST) -+ { -+ decoder->event.type = PIPELINE_EVENT_NONE; -+ WakeAllConditionVariable(&decoder->event_cv); -+ } -+ -+ LeaveCriticalSection(&decoder->event_cs); -+ -+ return ret; -+} -+ - static HRESULT WINAPI mf_decoder_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param) - { - FIXME("%p, %u %lu.\n", iface, message, param); -@@ -524,17 +740,315 @@ static HRESULT WINAPI mf_decoder_ProcessMessage(IMFTransform *iface, MFT_MESSAGE - - static HRESULT WINAPI mf_decoder_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags) - { -- FIXME("%p, %u, %p, %#x.\n", iface, id, sample, flags); -+ struct mf_decoder *decoder = impl_mf_decoder_from_IMFTransform(iface); -+ struct pipeline_event pip_event; -+ IMFMediaBuffer *buffer = NULL; -+ HRESULT hr = S_OK; -+ BYTE *buffer_data; -+ DWORD buffer_size; -+ uint32_t size = 0; -+ uint64_t offset; - -- return E_NOTIMPL; -+ TRACE("%p, %u, %p, %#x.\n", decoder, id, sample, flags); -+ -+ if (flags) -+ WARN("Unsupported flags %#x\n", flags); -+ -+ if (id != 0) -+ return MF_E_INVALIDSTREAMNUMBER; -+ -+ EnterCriticalSection(&decoder->cs); -+ -+ if (!decoder->input_type || !decoder->output_type) -+ { -+ LeaveCriticalSection(&decoder->cs); -+ return MF_E_TRANSFORM_TYPE_NOT_SET; -+ } -+ -+ if (decoder->draining) -+ { -+ LeaveCriticalSection(&decoder->cs); -+ return MF_E_NOTACCEPTING; -+ } -+ -+ if (!decoder->wg_stream) -+ { -+ pip_event = get_pipeline_event(decoder); -+ -+ switch (pip_event.type) -+ { -+ case PIPELINE_EVENT_PARSER_STARTED: -+ decoder->wg_stream = pip_event.u.parser_started.stream; -+ break; -+ case PIPELINE_EVENT_READ_REQUEST: -+ break; -+ default: -+ assert(0); -+ } -+ } -+ -+ if (decoder->wg_stream && !wg_parser_stream_drain(decoder->wg_stream)) -+ { -+ LeaveCriticalSection(&decoder->cs); -+ return MF_E_NOTACCEPTING; -+ } -+ -+ /* At this point, we either have a pre-init read request, or drained pipeline */ -+ -+ if (FAILED(hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer))) -+ goto done; -+ -+ if (FAILED(hr = IMFMediaBuffer_Lock(buffer, &buffer_data, NULL, &buffer_size))) -+ goto done; -+ -+ pip_event = get_pipeline_event(decoder); -+ assert(pip_event.type == PIPELINE_EVENT_READ_REQUEST); -+ -+ for(;;) -+ { -+ uint32_t copy_size; -+ -+ if (!wg_parser_get_next_read_offset(decoder->wg_parser, &offset, &size)) -+ continue; -+ -+ copy_size = min(size, buffer_size); -+ -+ if (offset != decoder->offset_tracker) -+ { -+ ERR("A seek is needed, MFTs don't support this!\n"); -+ wg_parser_push_data(decoder->wg_parser, WG_READ_FAILURE, NULL, 0); -+ IMFMediaBuffer_Unlock(buffer); -+ hr = E_FAIL; -+ goto done; -+ } -+ -+ wg_parser_push_data(decoder->wg_parser, WG_READ_SUCCESS, buffer_data, buffer_size); -+ -+ decoder->offset_tracker += copy_size; -+ -+ if (buffer_size <= size) -+ break; -+ -+ buffer_data += copy_size; -+ buffer_size -= copy_size; -+ -+ WARN("Input sample split into multiple read requests\n"); -+ } -+ -+ EnterCriticalSection(&decoder->event_cs); -+ decoder->event.type = PIPELINE_EVENT_NONE; -+ LeaveCriticalSection(&decoder->event_cs); -+ WakeAllConditionVariable(&decoder->event_cv); -+ -+ IMFMediaBuffer_Unlock(buffer); -+ -+ done: -+ if (buffer) -+ IMFMediaBuffer_Release(buffer); -+ LeaveCriticalSection(&decoder->cs); -+ return hr; - } - - static HRESULT WINAPI mf_decoder_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count, - MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status) - { -- FIXME("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status); -+ struct mf_decoder *decoder = impl_mf_decoder_from_IMFTransform(iface); -+ MFT_OUTPUT_DATA_BUFFER *relevant_buffer = NULL; -+ struct wg_parser_event event; -+ struct pipeline_event pip_event; -+ IMFMediaBuffer *buffer; -+ DWORD buffer_len; -+ unsigned int i; -+ BYTE *data; -+ HRESULT hr; - -- return E_NOTIMPL; -+ TRACE("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status); -+ -+ if (flags) -+ WARN("Unsupported flags %#x\n", flags); -+ -+ for (i = 0; i < count; i++) -+ { -+ MFT_OUTPUT_DATA_BUFFER *out_buffer = &samples[i]; -+ -+ if (out_buffer->dwStreamID != 0) -+ return MF_E_INVALIDSTREAMNUMBER; -+ -+ if (relevant_buffer) -+ return MF_E_INVALIDSTREAMNUMBER; -+ -+ relevant_buffer = out_buffer; -+ } -+ -+ if (!relevant_buffer) -+ return S_OK; -+ -+ EnterCriticalSection(&decoder->cs); -+ -+ if (!decoder->input_type || !decoder->output_type) -+ { -+ LeaveCriticalSection(&decoder->cs); -+ return MF_E_TRANSFORM_TYPE_NOT_SET; -+ } -+ -+ if (!decoder->wg_stream) -+ { -+ pip_event = get_pipeline_event(decoder); -+ -+ switch (pip_event.type) -+ { -+ case PIPELINE_EVENT_PARSER_STARTED: -+ decoder->wg_stream = pip_event.u.parser_started.stream; -+ break; -+ case PIPELINE_EVENT_READ_REQUEST: -+ LeaveCriticalSection(&decoder->cs); -+ return MF_E_TRANSFORM_NEED_MORE_INPUT; -+ default: -+ assert(0); -+ } -+ } -+ -+ if (wg_parser_stream_drain(decoder->wg_stream)) -+ { -+ /* this would be unexpected, as we should get the EOS-event when a drain command completes. */ -+ assert (!decoder->draining); -+ -+ LeaveCriticalSection(&decoder->cs); -+ return MF_E_TRANSFORM_NEED_MORE_INPUT; -+ } -+ -+ for (;;) -+ { -+ if (!wg_parser_stream_get_event(decoder->wg_stream, &event)) -+ { -+ LeaveCriticalSection(&decoder->cs); -+ return E_FAIL; -+ } -+ -+ if (event.type == WG_PARSER_EVENT_BUFFER) -+ break; -+ -+ if (event.type == WG_PARSER_EVENT_EOS) -+ { -+ if (!decoder->draining) -+ { -+ LeaveCriticalSection(&decoder->cs); -+ WARN("Received EOS event while not draining\n"); -+ return E_FAIL; -+ } -+ decoder->draining = FALSE; -+ LeaveCriticalSection(&decoder->cs); -+ return MF_E_TRANSFORM_NEED_MORE_INPUT; -+ } -+ -+ assert(event.type != WG_PARSER_EVENT_NONE); -+ } -+ -+ if (relevant_buffer->pSample) -+ { -+ if (FAILED(hr = IMFSample_ConvertToContiguousBuffer(relevant_buffer->pSample, &buffer))) -+ { -+ ERR("Failed to get buffer from sample, hr %#x.\n", hr); -+ LeaveCriticalSection(&decoder->cs); -+ return hr; -+ } -+ } -+ else -+ { -+ if (FAILED(hr = MFCreateMemoryBuffer(event.u.buffer.size, &buffer))) -+ { -+ ERR("Failed to create buffer, hr %#x.\n", hr); -+ LeaveCriticalSection(&decoder->cs); -+ return hr; -+ } -+ -+ if (FAILED(hr = MFCreateSample(&relevant_buffer->pSample))) -+ { -+ ERR("Failed to create sample, hr %#x.\n", hr); -+ LeaveCriticalSection(&decoder->cs); -+ IMFMediaBuffer_Release(buffer); -+ return hr; -+ } -+ -+ if (FAILED(hr = IMFSample_AddBuffer(relevant_buffer->pSample, buffer))) -+ { -+ ERR("Failed to add buffer, hr %#x.\n", hr); -+ goto out; -+ } -+ } -+ -+ if (FAILED(hr = IMFMediaBuffer_GetMaxLength(buffer, &buffer_len))) -+ { -+ ERR("Failed to get buffer size, hr %#x.\n", hr); -+ goto out; -+ } -+ -+ if (buffer_len < event.u.buffer.size) -+ { -+ WARN("Client's buffer is smaller (%u bytes) than the output sample (%u bytes)\n", -+ buffer_len, event.u.buffer.size); -+ -+ if (FAILED(hr = IMFMediaBuffer_SetCurrentLength(buffer, buffer_len))) -+ { -+ ERR("Failed to set size, hr %#x.\n", hr); -+ goto out; -+ } -+ } -+ else if (FAILED(hr = IMFMediaBuffer_SetCurrentLength(buffer, event.u.buffer.size))) -+ { -+ ERR("Failed to set size, hr %#x.\n", hr); -+ goto out; -+ } -+ -+ -+ if (FAILED(hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL))) -+ { -+ ERR("Failed to lock buffer, hr %#x.\n", hr); -+ goto out; -+ } -+ -+ if (!wg_parser_stream_copy_buffer(decoder->wg_stream, data, 0, min(buffer_len, event.u.buffer.size))) -+ { -+ hr = E_FAIL; -+ goto out; -+ } -+ -+ if (FAILED(hr = IMFMediaBuffer_Unlock(buffer))) -+ { -+ ERR("Failed to unlock buffer, hr %#x.\n", hr); -+ goto out; -+ } -+ -+ if (FAILED(hr = IMFSample_SetSampleTime(relevant_buffer->pSample, event.u.buffer.pts))) -+ { -+ ERR("Failed to set sample time, hr %#x.\n", hr); -+ goto out; -+ } -+ -+ if (FAILED(hr = IMFSample_SetSampleDuration(relevant_buffer->pSample, event.u.buffer.duration))) -+ { -+ ERR("Failed to set sample duration, hr %#x.\n", hr); -+ goto out; -+ } -+ -+ relevant_buffer->dwStatus = 0; -+ relevant_buffer->pEvents = NULL; -+ *status = 0; -+ -+ out: -+ if (SUCCEEDED(hr)) -+ wg_parser_stream_release_buffer(decoder->wg_stream); -+ LeaveCriticalSection(&decoder->cs); -+ -+ if (FAILED(hr)) -+ { -+ IMFSample_Release(relevant_buffer->pSample); -+ relevant_buffer->pSample = NULL; -+ } -+ -+ IMFMediaBuffer_Release(buffer); -+ -+ return hr; - } - - static const IMFTransformVtbl mf_decoder_vtbl = -@@ -570,6 +1084,7 @@ static const IMFTransformVtbl mf_decoder_vtbl = - HRESULT decode_transform_create(REFIID riid, void **obj, enum decoder_type type) - { - struct mf_decoder *object; -+ struct wg_parser *parser; - - TRACE("%s, %p %u.\n", debugstr_guid(riid), obj, type); - -@@ -583,6 +1098,21 @@ HRESULT decode_transform_create(REFIID riid, void **obj, enum decoder_type type) - object->video = decoder_descs[type].major_type == &MFMediaType_Video; - - InitializeCriticalSection(&object->cs); -+ InitializeCriticalSection(&object->help_cs); -+ InitializeCriticalSection(&object->event_cs); -+ InitializeConditionVariable(&object->help_cv); -+ InitializeConditionVariable(&object->event_cv); -+ -+ if (!(parser = wg_parser_create(WG_PARSER_DECODEBIN, TRUE))) -+ { -+ ERR("Failed to create Decoder MFT type %u: Unspecified GStreamer error\n", type); -+ IMFTransform_Release(&object->IMFTransform_iface); -+ return E_OUTOFMEMORY; -+ } -+ object->wg_parser = parser; -+ -+ object->helper_thread = CreateThread(NULL, 0, helper_thread_func, object, 0, NULL); -+ object->read_thread = CreateThread(NULL, 0, read_thread_func, object, 0, NULL); - - *obj = &object->IMFTransform_iface; - return S_OK; -diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index ab850b899f3..3d6202a209a 100644 ---- a/dlls/winegstreamer/wg_parser.c -+++ b/dlls/winegstreamer/wg_parser.c -@@ -2150,9 +2150,13 @@ static NTSTATUS wg_parser_disconnect(void *args) - - /* Unblock all of our streams. */ - pthread_mutex_lock(&parser->mutex); -+ parser->flushing = true; -+ parser->no_more_pads = true; -+ pthread_cond_signal(&parser->init_cond); - for (i = 0; i < parser->stream_count; ++i) - { - parser->streams[i]->flushing = true; -+ pthread_cond_signal(&parser->streams[i]->event_cond); - pthread_cond_signal(&parser->streams[i]->event_empty_cond); - } - pthread_mutex_unlock(&parser->mutex); --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0047-winegstreamer-Implement-ProcessMessage-for-decoder-t.patch b/patches/mfplat-streaming-support/0047-winegstreamer-Implement-ProcessMessage-for-decoder-t.patch deleted file mode 100644 index 1ee43492..00000000 --- a/patches/mfplat-streaming-support/0047-winegstreamer-Implement-ProcessMessage-for-decoder-t.patch +++ /dev/null @@ -1,121 +0,0 @@ -From d152c0c2bbd0bcb42b45fcde8f0ce2f13ba90eec Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Fri, 19 Mar 2021 16:54:03 -0400 -Subject: [PATCH 47/88] winegstreamer: Implement ::ProcessMessage for decoder - transform. - ---- - dlls/winegstreamer/decode_transform.c | 96 ++++++++++++++++++++++++++- - 1 file changed, 94 insertions(+), 2 deletions(-) - -diff --git a/dlls/winegstreamer/decode_transform.c b/dlls/winegstreamer/decode_transform.c -index c2b70c10f41..6f1363ff1f3 100644 ---- a/dlls/winegstreamer/decode_transform.c -+++ b/dlls/winegstreamer/decode_transform.c -@@ -733,9 +733,101 @@ static struct pipeline_event get_pipeline_event(struct mf_decoder *decoder) - - static HRESULT WINAPI mf_decoder_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param) - { -- FIXME("%p, %u %lu.\n", iface, message, param); -+ struct mf_decoder *decoder = impl_mf_decoder_from_IMFTransform(iface); -+ HRESULT hr; - -- return E_NOTIMPL; -+ TRACE("%p, %x %lu.\n", decoder, message, param); -+ -+ EnterCriticalSection(&decoder->cs); -+ if (!decoder->input_type || !decoder->output_type) -+ { -+ LeaveCriticalSection(&decoder->cs); -+ return MF_E_TRANSFORM_TYPE_NOT_SET; -+ } -+ -+ hr = S_OK; -+ -+ switch (message) -+ { -+ case MFT_MESSAGE_NOTIFY_BEGIN_STREAMING: -+ case MFT_MESSAGE_NOTIFY_START_OF_STREAM: -+ break; -+ case MFT_MESSAGE_NOTIFY_END_OF_STREAM: -+ { -+ if (param) -+ { -+ hr = MF_E_INVALIDSTREAMNUMBER; -+ break; -+ } -+ if (!decoder->wg_stream) -+ { -+ ERR("End-Of-Stream marked on a decoder MFT which hasn't finished initialization\n"); -+ hr = E_FAIL; -+ break; -+ } -+ -+ decoder->eos = TRUE; -+ break; -+ } -+ case MFT_MESSAGE_COMMAND_DRAIN: -+ { -+ struct pipeline_event pip_event; -+ -+ if (!decoder->wg_stream) -+ { -+ ERR("Drain requested on a decoder MFT which hasn't finished initialization\n"); -+ hr = E_FAIL; -+ break; -+ } -+ -+ pip_event = get_pipeline_event(decoder); -+ assert(pip_event.type == PIPELINE_EVENT_READ_REQUEST); -+ -+ wg_parser_push_data(decoder->wg_parser, WG_READ_EOS, NULL, 0); -+ -+ EnterCriticalSection(&decoder->event_cs); -+ decoder->event.type = PIPELINE_EVENT_NONE; -+ LeaveCriticalSection(&decoder->event_cs); -+ WakeAllConditionVariable(&decoder->event_cv); -+ -+ decoder->draining = TRUE; -+ decoder->offset_tracker = 0; -+ break; -+ } -+ case MFT_MESSAGE_COMMAND_FLUSH: -+ { -+ struct pipeline_event pip_event; -+ -+ if (!decoder->wg_stream) -+ { -+ ERR("Flush requested on a decoder MFT which hasn't finished initialization\n"); -+ hr = E_FAIL; -+ break; -+ } -+ -+ pip_event = get_pipeline_event(decoder); -+ assert(pip_event.type == PIPELINE_EVENT_READ_REQUEST); -+ -+ wg_parser_push_data(decoder->wg_parser, WG_READ_FLUSHING, NULL, 0); -+ -+ EnterCriticalSection(&decoder->event_cs); -+ decoder->event.type = PIPELINE_EVENT_NONE; -+ LeaveCriticalSection(&decoder->event_cs); -+ WakeAllConditionVariable(&decoder->event_cv); -+ -+ decoder->offset_tracker = 0; -+ break; -+ } -+ default: -+ { -+ ERR("Unhandled message type %x.\n", message); -+ hr = E_FAIL; -+ break; -+ } -+ } -+ -+ LeaveCriticalSection(&decoder->cs); -+ return hr; - } - - static HRESULT WINAPI mf_decoder_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags) --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0048-winegstreamer-Implement-Process-Input-Output-for-aud.patch b/patches/mfplat-streaming-support/0048-winegstreamer-Implement-Process-Input-Output-for-aud.patch deleted file mode 100644 index eff1db63..00000000 --- a/patches/mfplat-streaming-support/0048-winegstreamer-Implement-Process-Input-Output-for-aud.patch +++ /dev/null @@ -1,485 +0,0 @@ -From 12a15d2c61816d3d0f55da07fd349088a6042db0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Wed, 15 Dec 2021 10:59:45 +0100 -Subject: [PATCH 48/88] winegstreamer: Implement ::Process(Input/Output) for - audio conversion transform. - ---- - dlls/winegstreamer/audioconvert.c | 277 +++++++++++++++++++++++++++++- - dlls/winegstreamer/unixlib.h | 1 + - dlls/winegstreamer/wg_parser.c | 61 +++++++ - 3 files changed, 332 insertions(+), 7 deletions(-) - -diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c -index afa6bd682a6..e7c1fb97f23 100644 ---- a/dlls/winegstreamer/audioconvert.c -+++ b/dlls/winegstreamer/audioconvert.c -@@ -35,6 +35,10 @@ struct audio_converter - IMFMediaType *input_type; - IMFMediaType *output_type; - CRITICAL_SECTION cs; -+ BOOL buffer_inflight; -+ LONGLONG buffer_pts, buffer_dur; -+ struct wg_parser *parser; -+ struct wg_parser_stream *stream; - IMFAttributes *attributes, *output_attributes; - }; - -@@ -85,6 +89,10 @@ static ULONG WINAPI audio_converter_Release(IMFTransform *iface) - IMFAttributes_Release(transform->attributes); - if (transform->output_attributes) - IMFAttributes_Release(transform->output_attributes); -+ if (transform->stream) -+ wg_parser_disconnect(transform->parser); -+ if (transform->parser) -+ wg_parser_destroy(transform->parser); - free(transform); - } - -@@ -324,6 +332,7 @@ fail: - static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) - { - GUID major_type, subtype; -+ struct wg_format format; - UINT32 unused; - HRESULT hr; - -@@ -343,6 +352,11 @@ static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id - - if (converter->input_type) - { -+ if (converter->stream) -+ { -+ wg_parser_disconnect(converter->parser); -+ converter->stream = NULL; -+ } - IMFMediaType_Release(converter->input_type); - converter->input_type = NULL; - } -@@ -369,6 +383,10 @@ static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id - if (!IsEqualGUID(&subtype, &MFAudioFormat_PCM) && !IsEqualGUID(&subtype, &MFAudioFormat_Float)) - return MF_E_INVALIDTYPE; - -+ mf_media_type_to_wg_format(type, &format); -+ if (!format.major_type) -+ return MF_E_INVALIDTYPE; -+ - if (flags & MFT_SET_TYPE_TEST_ONLY) - return S_OK; - -@@ -388,6 +406,21 @@ static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id - converter->input_type = NULL; - } - -+ if (converter->stream) -+ { -+ wg_parser_disconnect(converter->parser); -+ converter->stream = NULL; -+ } -+ -+ if (converter->input_type && converter->output_type) -+ { -+ struct wg_format output_format; -+ mf_media_type_to_wg_format(converter->output_type, &output_format); -+ -+ if (SUCCEEDED(hr = wg_parser_connect_unseekable(converter->parser, &format, 1, &output_format))) -+ converter->stream = wg_parser_get_stream(converter->parser, 0); -+ } -+ - LeaveCriticalSection(&converter->cs); - - return hr; -@@ -397,6 +430,7 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i - { - struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface); - GUID major_type, subtype; -+ struct wg_format format; - UINT32 unused; - HRESULT hr; - -@@ -405,9 +439,6 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i - if (id != 0) - return MF_E_INVALIDSTREAMNUMBER; - -- if (!converter->input_type) -- return MF_E_TRANSFORM_TYPE_NOT_SET; -- - if (!type) - { - if (flags & MFT_SET_TYPE_TEST_ONLY) -@@ -417,6 +448,11 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i - - if (converter->output_type) - { -+ if (converter->stream) -+ { -+ wg_parser_disconnect(converter->parser); -+ converter->stream = NULL; -+ } - IMFMediaType_Release(converter->output_type); - converter->output_type = NULL; - } -@@ -443,6 +479,10 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i - if (!IsEqualGUID(&subtype, &MFAudioFormat_PCM) && !IsEqualGUID(&subtype, &MFAudioFormat_Float)) - return MF_E_INVALIDTYPE; - -+ mf_media_type_to_wg_format(type, &format); -+ if (!format.major_type) -+ return MF_E_INVALIDTYPE; -+ - if (flags & MFT_SET_TYPE_TEST_ONLY) - return S_OK; - -@@ -462,6 +502,21 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i - converter->output_type = NULL; - } - -+ if (converter->stream) -+ { -+ wg_parser_disconnect(converter->parser); -+ converter->stream = NULL; -+ } -+ -+ if (converter->input_type && converter->output_type) -+ { -+ struct wg_format input_format; -+ mf_media_type_to_wg_format(converter->input_type, &input_format); -+ -+ if (SUCCEEDED(hr = wg_parser_connect_unseekable(converter->parser, &input_format, 1, &format))) -+ converter->stream = wg_parser_get_stream(converter->parser, 0); -+ } -+ - LeaveCriticalSection(&converter->cs); - - return hr; -@@ -574,17 +629,218 @@ static HRESULT WINAPI audio_converter_ProcessMessage(IMFTransform *iface, MFT_ME - - static HRESULT WINAPI audio_converter_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags) - { -- FIXME("%p, %lu, %p, %#lx.\n", iface, id, sample, flags); -+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface); -+ IMFMediaBuffer *buffer = NULL; -+ unsigned char *buffer_data; -+ DWORD buffer_size; -+ uint64_t offset; -+ uint32_t size; -+ HRESULT hr; - -- return E_NOTIMPL; -+ TRACE("%p, %lu, %p, %#lx.\n", iface, id, sample, flags); -+ -+ if (flags) -+ WARN("Unsupported flags %#lx.\n", flags); -+ -+ if (id != 0) -+ return MF_E_INVALIDSTREAMNUMBER; -+ -+ EnterCriticalSection(&converter->cs); -+ -+ if (!converter->stream) -+ { -+ hr = MF_E_TRANSFORM_TYPE_NOT_SET; -+ goto done; -+ } -+ -+ if (converter->buffer_inflight) -+ { -+ hr = MF_E_NOTACCEPTING; -+ goto done; -+ } -+ -+ if (FAILED(hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer))) -+ goto done; -+ -+ if (FAILED(hr = IMFMediaBuffer_Lock(buffer, &buffer_data, NULL, &buffer_size))) -+ goto done; -+ -+ for (;;) -+ { -+ if (!wg_parser_get_next_read_offset(converter->parser, &offset, &size)) -+ continue; -+ -+ wg_parser_push_data(converter->parser, WG_READ_SUCCESS, buffer_data, min(buffer_size, size)); -+ -+ if (buffer_size <= size) -+ break; -+ -+ buffer_data += size; -+ buffer_size -= size; -+ } -+ -+ IMFMediaBuffer_Unlock(buffer); -+ converter->buffer_inflight = TRUE; -+ if (FAILED(IMFSample_GetSampleTime(sample, &converter->buffer_pts))) -+ converter->buffer_pts = -1; -+ if (FAILED(IMFSample_GetSampleDuration(sample, &converter->buffer_dur))) -+ converter->buffer_dur = -1; -+ -+done: -+ if (buffer) -+ IMFMediaBuffer_Release(buffer); -+ LeaveCriticalSection(&converter->cs); -+ return hr; - } - - static HRESULT WINAPI audio_converter_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count, - MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status) - { -- FIXME("%p, %#lx, %lu, %p, %p.\n", iface, flags, count, samples, status); -+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface); -+ IMFSample *allocated_sample = NULL; -+ IMFMediaBuffer *buffer = NULL; -+ struct wg_parser_event event; -+ unsigned char *buffer_data; -+ DWORD buffer_len; -+ HRESULT hr = S_OK; - -- return E_NOTIMPL; -+ TRACE("%p, %#lx, %lu, %p, %p.\n", iface, flags, count, samples, status); -+ -+ if (flags) -+ WARN("Unsupported flags %#lx.\n", flags); -+ -+ if (!count) -+ return S_OK; -+ -+ if (count != 1) -+ return MF_E_INVALIDSTREAMNUMBER; -+ -+ if (samples[0].dwStreamID != 0) -+ return MF_E_INVALIDSTREAMNUMBER; -+ -+ EnterCriticalSection(&converter->cs); -+ -+ if (!converter->stream) -+ { -+ hr = MF_E_TRANSFORM_TYPE_NOT_SET; -+ goto done; -+ } -+ -+ if (!converter->buffer_inflight) -+ { -+ hr = MF_E_TRANSFORM_NEED_MORE_INPUT; -+ goto done; -+ } -+ -+ for (;;) -+ { -+ wg_parser_stream_get_event(converter->stream, &event); -+ -+ switch (event.type) -+ { -+ case WG_PARSER_EVENT_BUFFER: -+ break; -+ -+ case WG_PARSER_EVENT_SEGMENT: -+ continue; -+ -+ default: -+ WARN("Unexpected event, %lu\n", event.type); -+ continue; -+ } -+ break; -+ } -+ -+ if (!samples[0].pSample) -+ { -+ if (FAILED(hr = MFCreateMemoryBuffer(event.u.buffer.size, &buffer))) -+ { -+ ERR("Failed to create buffer, hr %#lx.\n", hr); -+ goto done; -+ } -+ -+ if (FAILED(hr = MFCreateSample(&allocated_sample))) -+ { -+ ERR("Failed to create sample, hr %#lx.\n", hr); -+ goto done; -+ } -+ -+ samples[0].pSample = allocated_sample; -+ -+ if (FAILED(hr = IMFSample_AddBuffer(samples[0].pSample, buffer))) -+ { -+ ERR("Failed to add buffer, hr %#lx.\n", hr); -+ goto done; -+ } -+ -+ IMFMediaBuffer_Release(buffer); -+ buffer = NULL; -+ } -+ -+ if (FAILED(hr = IMFSample_ConvertToContiguousBuffer(samples[0].pSample, &buffer))) -+ { -+ ERR("Failed to get buffer from sample, hr %#lx.\n", hr); -+ goto done; -+ } -+ -+ if (FAILED(hr = IMFMediaBuffer_GetMaxLength(buffer, &buffer_len))) -+ { -+ ERR("Failed to get buffer size, hr %#lx.\n", hr); -+ goto done; -+ } -+ -+ if (buffer_len < event.u.buffer.size) -+ { -+ WARN("Client's buffer is smaller (%lu bytes) than the output sample (%lu bytes)\n", -+ buffer_len, event.u.buffer.size); -+ -+ hr = MF_E_BUFFERTOOSMALL; -+ goto done; -+ } -+ -+ if (FAILED(hr = IMFMediaBuffer_SetCurrentLength(buffer, event.u.buffer.size))) -+ { -+ ERR("Failed to set size, hr %#lx.\n", hr); -+ goto done; -+ } -+ -+ if (FAILED(hr = IMFMediaBuffer_Lock(buffer, &buffer_data, NULL, NULL))) -+ { -+ ERR("Failed to lock buffer hr %#lx.\n", hr); -+ goto done; -+ } -+ -+ if (!wg_parser_stream_copy_buffer(converter->stream, buffer_data, 0, event.u.buffer.size)) -+ { -+ ERR("Failed to copy buffer.\n"); -+ IMFMediaBuffer_Unlock(buffer); -+ hr = E_FAIL; -+ goto done; -+ } -+ -+ IMFMediaBuffer_Unlock(buffer); -+ -+ wg_parser_stream_release_buffer(converter->stream); -+ converter->buffer_inflight = FALSE; -+ -+ if (converter->buffer_pts != -1) -+ IMFSample_SetSampleTime(samples[0].pSample, converter->buffer_pts); -+ if (converter->buffer_dur != -1) -+ IMFSample_SetSampleDuration(samples[0].pSample, converter->buffer_dur); -+ -+ samples[0].dwStatus = 0; -+ samples[0].pEvents = NULL; -+ -+ done: -+ if (buffer) -+ IMFMediaBuffer_Release(buffer); -+ if (allocated_sample && FAILED(hr)) -+ { -+ IMFSample_Release(allocated_sample); -+ samples[0].pSample = NULL; -+ } -+ LeaveCriticalSection(&converter->cs); -+ return hr; - } - - static const IMFTransformVtbl audio_converter_vtbl = -@@ -645,6 +901,13 @@ HRESULT audio_converter_create(REFIID riid, void **ret) - return hr; - } - -+ if (!(object->parser = wg_parser_create(WG_PARSER_AUDIOCONV, true))) -+ { -+ ERR("Failed to create audio converter due to GStreamer error.\n"); -+ IMFTransform_Release(&object->IMFTransform_iface); -+ return E_OUTOFMEMORY; -+ } -+ - *ret = &object->IMFTransform_iface; - return S_OK; - } -diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h -index e5d87716734..df5e48ef3c9 100644 ---- a/dlls/winegstreamer/unixlib.h -+++ b/dlls/winegstreamer/unixlib.h -@@ -160,6 +160,7 @@ enum wg_parser_type - WG_PARSER_AVIDEMUX, - WG_PARSER_MPEGAUDIOPARSE, - WG_PARSER_WAVPARSE, -+ WG_PARSER_AUDIOCONV, - }; - - struct wg_parser_create_params -diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index 3d6202a209a..ee59951d2de 100644 ---- a/dlls/winegstreamer/wg_parser.c -+++ b/dlls/winegstreamer/wg_parser.c -@@ -2327,6 +2327,66 @@ static BOOL wave_parser_init_gst(struct wg_parser *parser) - return TRUE; - } - -+static BOOL audio_convert_init_gst(struct wg_parser *parser) -+{ -+ struct wg_parser_stream *stream; -+ GstElement *convert, *resampler; -+ int ret; -+ -+ if (parser->seekable) -+ return FALSE; -+ -+ if (parser->expected_stream_count != 1) -+ return FALSE; -+ -+ if (parser->input_format.major_type != WG_MAJOR_TYPE_AUDIO) -+ return FALSE; -+ -+ if (!(convert = create_element("audioconvert", "base"))) -+ return FALSE; -+ -+ gst_bin_add(GST_BIN(parser->container), convert); -+ -+ if (!(resampler = create_element("audioresample", "base"))) -+ return FALSE; -+ -+ gst_bin_add(GST_BIN(parser->container), resampler); -+ -+ gst_element_link(convert, resampler); -+ -+ parser->their_sink = gst_element_get_static_pad(convert, "sink"); -+ if ((ret = gst_pad_link(parser->my_src, parser->their_sink)) < 0) -+ { -+ GST_ERROR("Failed to link sink pads, error %d.\n", ret); -+ return FALSE; -+ } -+ -+ if (!(stream = create_stream(parser))) -+ return FALSE; -+ -+ stream->their_src = gst_element_get_static_pad(resampler, "src"); -+ gst_object_ref(stream->their_src); -+ if ((ret = gst_pad_link(stream->their_src, stream->my_sink)) < 0) -+ { -+ GST_ERROR("Failed to link source pads, error %d.\n", ret); -+ return FALSE; -+ } -+ gst_pad_set_active(stream->my_sink, 1); -+ -+ parser->no_more_pads = true; -+ -+ gst_element_set_state(parser->container, GST_STATE_PAUSED); -+ gst_pad_set_active(parser->my_src, 1); -+ ret = gst_element_get_state(parser->container, NULL, NULL, -1); -+ if (ret == GST_STATE_CHANGE_FAILURE) -+ { -+ GST_ERROR("Failed to play stream.\n"); -+ return FALSE; -+ } -+ -+ return TRUE; -+} -+ - static void init_gstreamer_once(void) - { - char arg0[] = "wine"; -@@ -2373,6 +2433,7 @@ static NTSTATUS wg_parser_create(void *args) - [WG_PARSER_AVIDEMUX] = avi_parser_init_gst, - [WG_PARSER_MPEGAUDIOPARSE] = mpeg_audio_parser_init_gst, - [WG_PARSER_WAVPARSE] = wave_parser_init_gst, -+ [WG_PARSER_AUDIOCONV] = audio_convert_init_gst, - }; - - static pthread_once_t once = PTHREAD_ONCE_INIT; --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0049-winegstreamer-Implement-Process-Input-Output-for-col.patch b/patches/mfplat-streaming-support/0049-winegstreamer-Implement-Process-Input-Output-for-col.patch deleted file mode 100644 index b82f803d..00000000 --- a/patches/mfplat-streaming-support/0049-winegstreamer-Implement-Process-Input-Output-for-col.patch +++ /dev/null @@ -1,472 +0,0 @@ -From f0c91d2a459177e0abb5d26d54a87d27276e554c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Wed, 15 Dec 2021 13:30:39 +0100 -Subject: [PATCH 49/88] winegstreamer: Implement ::Process(Input/Output) for - color conversion transform. - ---- - dlls/winegstreamer/colorconvert.c | 276 +++++++++++++++++++++++++++++- - dlls/winegstreamer/unixlib.h | 1 + - dlls/winegstreamer/wg_parser.c | 54 ++++++ - 3 files changed, 326 insertions(+), 5 deletions(-) - -diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c -index baf429d42f9..99788bf7f92 100644 ---- a/dlls/winegstreamer/colorconvert.c -+++ b/dlls/winegstreamer/colorconvert.c -@@ -51,6 +51,10 @@ struct color_converter - IMFMediaType *input_type; - IMFMediaType *output_type; - CRITICAL_SECTION cs; -+ BOOL buffer_inflight; -+ LONGLONG buffer_pts, buffer_dur; -+ struct wg_parser *parser; -+ struct wg_parser_stream *stream; - }; - - static struct color_converter *impl_color_converter_from_IMFTransform(IMFTransform *iface) -@@ -98,6 +102,10 @@ static ULONG WINAPI color_converter_Release(IMFTransform *iface) - DeleteCriticalSection(&transform->cs); - if (transform->output_type) - IMFMediaType_Release(transform->output_type); -+ if (transform->stream) -+ wg_parser_disconnect(transform->parser); -+ if (transform->parser) -+ wg_parser_destroy(transform->parser); - free(transform); - } - -@@ -319,6 +327,7 @@ static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id - struct color_converter *converter = impl_color_converter_from_IMFTransform(iface); - UINT64 input_framesize, output_framesize; - GUID major_type, subtype; -+ struct wg_format format; - unsigned int i; - HRESULT hr; - -@@ -336,6 +345,11 @@ static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id - - if (converter->input_type) - { -+ if (converter->stream) -+ { -+ wg_parser_disconnect(converter->parser); -+ converter->stream = NULL; -+ } - IMFMediaType_Release(converter->input_type); - converter->input_type = NULL; - } -@@ -375,6 +389,10 @@ static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id - - LeaveCriticalSection(&converter->cs); - -+ mf_media_type_to_wg_format(type, &format); -+ if (!format.major_type) -+ return MF_E_INVALIDTYPE; -+ - if (flags & MFT_SET_TYPE_TEST_ONLY) - return S_OK; - -@@ -394,6 +412,21 @@ static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id - converter->input_type = NULL; - } - -+ if (converter->stream) -+ { -+ wg_parser_disconnect(converter->parser); -+ converter->stream = NULL; -+ } -+ -+ if (converter->input_type && converter->output_type) -+ { -+ struct wg_format output_format; -+ mf_media_type_to_wg_format(converter->output_type, &output_format); -+ -+ if (SUCCEEDED(hr = wg_parser_connect_unseekable(converter->parser, &format, 1, &output_format))) -+ converter->stream = wg_parser_get_stream(converter->parser, 0); -+ } -+ - LeaveCriticalSection(&converter->cs); - - return hr; -@@ -404,6 +437,7 @@ static HRESULT WINAPI color_converter_SetOutputType(IMFTransform *iface, DWORD i - struct color_converter *converter = impl_color_converter_from_IMFTransform(iface); - UINT64 input_framesize, output_framesize; - GUID major_type, subtype; -+ struct wg_format format; - unsigned int i; - HRESULT hr; - -@@ -421,6 +455,11 @@ static HRESULT WINAPI color_converter_SetOutputType(IMFTransform *iface, DWORD i - - if (converter->output_type) - { -+ if (converter->stream) -+ { -+ wg_parser_disconnect(converter->parser); -+ converter->stream = NULL; -+ } - IMFMediaType_Release(converter->output_type); - converter->output_type = NULL; - } -@@ -460,6 +499,10 @@ static HRESULT WINAPI color_converter_SetOutputType(IMFTransform *iface, DWORD i - - LeaveCriticalSection(&converter->cs); - -+ mf_media_type_to_wg_format(type, &format); -+ if (!format.major_type) -+ return MF_E_INVALIDTYPE; -+ - if (flags & MFT_SET_TYPE_TEST_ONLY) - return S_OK; - -@@ -479,9 +522,24 @@ static HRESULT WINAPI color_converter_SetOutputType(IMFTransform *iface, DWORD i - converter->output_type = NULL; - } - -+ if (converter->stream) -+ { -+ wg_parser_disconnect(converter->parser); -+ converter->stream = NULL; -+ } -+ -+ if (converter->input_type && converter->output_type) -+ { -+ struct wg_format input_format; -+ mf_media_type_to_wg_format(converter->input_type, &input_format); -+ -+ if (SUCCEEDED(hr = wg_parser_connect_unseekable(converter->parser, &input_format, 1, &format))) -+ converter->stream = wg_parser_get_stream(converter->parser, 0); -+ } -+ - LeaveCriticalSection(&converter->cs); - -- return S_OK; -+ return hr; - } - - static HRESULT WINAPI color_converter_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) -@@ -567,17 +625,218 @@ static HRESULT WINAPI color_converter_ProcessMessage(IMFTransform *iface, MFT_ME - - static HRESULT WINAPI color_converter_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags) - { -- FIXME("%p, %u, %p, %#x.\n", iface, id, sample, flags); -+ struct color_converter *converter = impl_color_converter_from_IMFTransform(iface); -+ IMFMediaBuffer *buffer = NULL; -+ unsigned char *buffer_data; -+ DWORD buffer_size; -+ uint64_t offset; -+ uint32_t size; -+ HRESULT hr; - -- return E_NOTIMPL; -+ TRACE("%p, %u, %p, %#x.\n", iface, id, sample, flags); -+ -+ if (flags) -+ WARN("Unsupported flags %#x.\n", flags); -+ -+ if (id != 0) -+ return MF_E_INVALIDSTREAMNUMBER; -+ -+ EnterCriticalSection(&converter->cs); -+ -+ if (!converter->stream) -+ { -+ hr = MF_E_TRANSFORM_TYPE_NOT_SET; -+ goto done; -+ } -+ -+ if (converter->buffer_inflight) -+ { -+ hr = MF_E_NOTACCEPTING; -+ goto done; -+ } -+ -+ if (FAILED(hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer))) -+ goto done; -+ -+ if (FAILED(hr = IMFMediaBuffer_Lock(buffer, &buffer_data, NULL, &buffer_size))) -+ goto done; -+ -+ for (;;) -+ { -+ if (!wg_parser_get_next_read_offset(converter->parser, &offset, &size)) -+ continue; -+ -+ wg_parser_push_data(converter->parser, WG_READ_SUCCESS, buffer_data, min(buffer_size, size)); -+ -+ if (buffer_size <= size) -+ break; -+ -+ buffer_data += size; -+ buffer_size -= size; -+ } -+ -+ IMFMediaBuffer_Unlock(buffer); -+ converter->buffer_inflight = TRUE; -+ if (FAILED(IMFSample_GetSampleTime(sample, &converter->buffer_pts))) -+ converter->buffer_pts = -1; -+ if (FAILED(IMFSample_GetSampleDuration(sample, &converter->buffer_dur))) -+ converter->buffer_dur = -1; -+ -+done: -+ if (buffer) -+ IMFMediaBuffer_Release(buffer); -+ LeaveCriticalSection(&converter->cs); -+ return hr; - } - - static HRESULT WINAPI color_converter_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count, - MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status) - { -- FIXME("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status); -+ struct color_converter *converter = impl_color_converter_from_IMFTransform(iface); -+ IMFSample *allocated_sample = NULL; -+ IMFMediaBuffer *buffer = NULL; -+ struct wg_parser_event event; -+ unsigned char *buffer_data; -+ DWORD buffer_len; -+ HRESULT hr = S_OK; - -- return E_NOTIMPL; -+ TRACE("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status); -+ -+ if (flags) -+ WARN("Unsupported flags %#x.\n", flags); -+ -+ if (!count) -+ return S_OK; -+ -+ if (count != 1) -+ return MF_E_INVALIDSTREAMNUMBER; -+ -+ if (samples[0].dwStreamID != 0) -+ return MF_E_INVALIDSTREAMNUMBER; -+ -+ EnterCriticalSection(&converter->cs); -+ -+ if (!converter->stream) -+ { -+ hr = MF_E_TRANSFORM_TYPE_NOT_SET; -+ goto done; -+ } -+ -+ if (!converter->buffer_inflight) -+ { -+ hr = MF_E_TRANSFORM_NEED_MORE_INPUT; -+ goto done; -+ } -+ -+ for (;;) -+ { -+ wg_parser_stream_get_event(converter->stream, &event); -+ -+ switch (event.type) -+ { -+ case WG_PARSER_EVENT_BUFFER: -+ break; -+ -+ case WG_PARSER_EVENT_SEGMENT: -+ continue; -+ -+ default: -+ WARN("Unexpected event, %u\n", event.type); -+ continue; -+ } -+ break; -+ } -+ -+ if (!samples[0].pSample) -+ { -+ if (FAILED(hr = MFCreateMemoryBuffer(event.u.buffer.size, &buffer))) -+ { -+ ERR("Failed to create buffer, hr %#x.\n", hr); -+ goto done; -+ } -+ -+ if (FAILED(hr = MFCreateSample(&allocated_sample))) -+ { -+ ERR("Failed to create sample, hr %#x.\n", hr); -+ goto done; -+ } -+ -+ samples[0].pSample = allocated_sample; -+ -+ if (FAILED(hr = IMFSample_AddBuffer(samples[0].pSample, buffer))) -+ { -+ ERR("Failed to add buffer, hr %#x.\n", hr); -+ goto done; -+ } -+ -+ IMFMediaBuffer_Release(buffer); -+ buffer = NULL; -+ } -+ -+ if (FAILED(hr = IMFSample_ConvertToContiguousBuffer(samples[0].pSample, &buffer))) -+ { -+ ERR("Failed to get buffer from sample, hr %#x.\n", hr); -+ goto done; -+ } -+ -+ if (FAILED(hr = IMFMediaBuffer_GetMaxLength(buffer, &buffer_len))) -+ { -+ ERR("Failed to get buffer size, hr %#x.\n", hr); -+ goto done; -+ } -+ -+ if (buffer_len < event.u.buffer.size) -+ { -+ WARN("Client's buffer is smaller (%u bytes) than the output sample (%u bytes)\n", -+ buffer_len, event.u.buffer.size); -+ -+ hr = MF_E_BUFFERTOOSMALL; -+ goto done; -+ } -+ -+ if (FAILED(hr = IMFMediaBuffer_SetCurrentLength(buffer, event.u.buffer.size))) -+ { -+ ERR("Failed to set size, hr %#x.\n", hr); -+ goto done; -+ } -+ -+ if (FAILED(hr = IMFMediaBuffer_Lock(buffer, &buffer_data, NULL, NULL))) -+ { -+ ERR("Failed to lock buffer hr %#x.\n", hr); -+ goto done; -+ } -+ -+ if (!wg_parser_stream_copy_buffer(converter->stream, buffer_data, 0, event.u.buffer.size)) -+ { -+ ERR("Failed to copy buffer.\n"); -+ IMFMediaBuffer_Unlock(buffer); -+ hr = E_FAIL; -+ goto done; -+ } -+ -+ IMFMediaBuffer_Unlock(buffer); -+ -+ wg_parser_stream_release_buffer(converter->stream); -+ converter->buffer_inflight = FALSE; -+ -+ if (converter->buffer_pts != -1) -+ IMFSample_SetSampleTime(samples[0].pSample, converter->buffer_pts); -+ if (converter->buffer_dur != -1) -+ IMFSample_SetSampleDuration(samples[0].pSample, converter->buffer_dur); -+ -+ samples[0].dwStatus = 0; -+ samples[0].pEvents = NULL; -+ -+ done: -+ if (buffer) -+ IMFMediaBuffer_Release(buffer); -+ if (FAILED(hr) && allocated_sample) -+ { -+ IMFSample_Release(allocated_sample); -+ samples[0].pSample = NULL; -+ } -+ LeaveCriticalSection(&converter->cs); -+ return hr; - } - - static const IMFTransformVtbl color_converter_vtbl = -@@ -625,6 +884,13 @@ HRESULT color_converter_create(REFIID riid, void **ret) - InitializeCriticalSection(&object->cs); - object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": color_converter_lock"); - -+ if (!(object->parser = wg_parser_create(WG_PARSER_VIDEOCONV, true))) -+ { -+ ERR("Failed to create video converter due to GStreamer error.\n"); -+ IMFTransform_Release(&object->IMFTransform_iface); -+ return E_OUTOFMEMORY; -+ } -+ - *ret = &object->IMFTransform_iface; - return S_OK; - } -diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h -index df5e48ef3c9..17b5c606014 100644 ---- a/dlls/winegstreamer/unixlib.h -+++ b/dlls/winegstreamer/unixlib.h -@@ -161,6 +161,7 @@ enum wg_parser_type - WG_PARSER_MPEGAUDIOPARSE, - WG_PARSER_WAVPARSE, - WG_PARSER_AUDIOCONV, -+ WG_PARSER_VIDEOCONV, - }; - - struct wg_parser_create_params -diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index ee59951d2de..06e07b874bf 100644 ---- a/dlls/winegstreamer/wg_parser.c -+++ b/dlls/winegstreamer/wg_parser.c -@@ -2387,6 +2387,59 @@ static BOOL audio_convert_init_gst(struct wg_parser *parser) - return TRUE; - } - -+static BOOL video_convert_init_gst(struct wg_parser *parser) -+{ -+ struct wg_parser_stream *stream; -+ GstElement *convert; -+ int ret; -+ -+ if (parser->seekable) -+ return FALSE; -+ -+ if (parser->expected_stream_count != 1) -+ return FALSE; -+ -+ if (parser->input_format.major_type != WG_MAJOR_TYPE_VIDEO) -+ return FALSE; -+ -+ if (!(convert = create_element("videoconvert", "base"))) -+ return FALSE; -+ -+ gst_bin_add(GST_BIN(parser->container), convert); -+ -+ parser->their_sink = gst_element_get_static_pad(convert, "sink"); -+ if ((ret = gst_pad_link(parser->my_src, parser->their_sink)) < 0) -+ { -+ GST_ERROR("Failed to link sink pads, error %d.\n", ret); -+ return FALSE; -+ } -+ -+ if (!(stream = create_stream(parser))) -+ return FALSE; -+ -+ stream->their_src = gst_element_get_static_pad(convert, "src"); -+ gst_object_ref(stream->their_src); -+ if ((ret = gst_pad_link(stream->their_src, stream->my_sink)) < 0) -+ { -+ GST_ERROR("Failed to link source pads, error %d.\n", ret); -+ return FALSE; -+ } -+ gst_pad_set_active(stream->my_sink, 1); -+ -+ parser->no_more_pads = true; -+ -+ gst_element_set_state(parser->container, GST_STATE_PAUSED); -+ gst_pad_set_active(parser->my_src, 1); -+ ret = gst_element_get_state(parser->container, NULL, NULL, -1); -+ if (ret == GST_STATE_CHANGE_FAILURE) -+ { -+ GST_ERROR("Failed to play stream.\n"); -+ return FALSE; -+ } -+ -+ return TRUE; -+} -+ - static void init_gstreamer_once(void) - { - char arg0[] = "wine"; -@@ -2434,6 +2487,7 @@ static NTSTATUS wg_parser_create(void *args) - [WG_PARSER_MPEGAUDIOPARSE] = mpeg_audio_parser_init_gst, - [WG_PARSER_WAVPARSE] = wave_parser_init_gst, - [WG_PARSER_AUDIOCONV] = audio_convert_init_gst, -+ [WG_PARSER_VIDEOCONV] = video_convert_init_gst, - }; - - static pthread_once_t once = PTHREAD_ONCE_INIT; --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0051-winegstreamer-Implement-MFT_MESSAGE_COMMAND_FLUSH-fo.patch b/patches/mfplat-streaming-support/0051-winegstreamer-Implement-MFT_MESSAGE_COMMAND_FLUSH-fo.patch deleted file mode 100644 index 3e973515..00000000 --- a/patches/mfplat-streaming-support/0051-winegstreamer-Implement-MFT_MESSAGE_COMMAND_FLUSH-fo.patch +++ /dev/null @@ -1,97 +0,0 @@ -From 39b907ca8de07e2bc78f173083fea717970847a2 Mon Sep 17 00:00:00 2001 -From: Derek Lesho -Date: Mon, 22 Mar 2021 15:50:51 -0400 -Subject: [PATCH 51/88] winegstreamer: Implement MFT_MESSAGE_COMMAND_FLUSH for - media converters. - ---- - dlls/winegstreamer/audioconvert.c | 20 ++++++++++++++++++++ - dlls/winegstreamer/colorconvert.c | 23 +++++++++++++++++++++++ - 2 files changed, 43 insertions(+) - -diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c -index e7c1fb97f23..f8d5833aa22 100644 ---- a/dlls/winegstreamer/audioconvert.c -+++ b/dlls/winegstreamer/audioconvert.c -@@ -614,11 +614,31 @@ static HRESULT WINAPI audio_converter_ProcessEvent(IMFTransform *iface, DWORD id - - static HRESULT WINAPI audio_converter_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param) - { -+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface); -+ struct wg_parser_event event; -+ - TRACE("%p, %u, %Iu.\n", iface, message, param); - - switch(message) - { - case MFT_MESSAGE_COMMAND_FLUSH: -+ { -+ EnterCriticalSection(&converter->cs); -+ if (!converter->buffer_inflight) -+ { -+ LeaveCriticalSection(&converter->cs); -+ return S_OK; -+ } -+ -+ while (event.type != WG_PARSER_EVENT_BUFFER) -+ wg_parser_stream_get_event(converter->stream, &event); -+ -+ wg_parser_stream_release_buffer(converter->stream); -+ converter->buffer_inflight = FALSE; -+ -+ LeaveCriticalSection(&converter->cs); -+ return S_OK; -+ } - case MFT_MESSAGE_NOTIFY_BEGIN_STREAMING: - return S_OK; - default: -diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c -index 99788bf7f92..6cad0c1706d 100644 ---- a/dlls/winegstreamer/colorconvert.c -+++ b/dlls/winegstreamer/colorconvert.c -@@ -610,11 +610,31 @@ static HRESULT WINAPI color_converter_ProcessEvent(IMFTransform *iface, DWORD id - - static HRESULT WINAPI color_converter_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param) - { -+ struct color_converter *converter = impl_color_converter_from_IMFTransform(iface); -+ struct wg_parser_event event; -+ - TRACE("%p, %u %lu.\n", iface, message, param); - - switch(message) - { - case MFT_MESSAGE_COMMAND_FLUSH: -+ { -+ EnterCriticalSection(&converter->cs); -+ if (!converter->buffer_inflight) -+ { -+ LeaveCriticalSection(&converter->cs); -+ return S_OK; -+ } -+ -+ while (event.type != WG_PARSER_EVENT_BUFFER) -+ wg_parser_stream_get_event(converter->stream, &event); -+ -+ wg_parser_stream_release_buffer(converter->stream); -+ converter->buffer_inflight = FALSE; -+ -+ LeaveCriticalSection(&converter->cs); -+ return S_OK; -+ } - case MFT_MESSAGE_NOTIFY_BEGIN_STREAMING: - return S_OK; - default: -@@ -664,7 +684,10 @@ static HRESULT WINAPI color_converter_ProcessInput(IMFTransform *iface, DWORD id - for (;;) - { - if (!wg_parser_get_next_read_offset(converter->parser, &offset, &size)) -+ { -+ TRACE("sink unconnected\n"); - continue; -+ } - - wg_parser_push_data(converter->parser, WG_READ_SUCCESS, buffer_data, min(buffer_size, size)); - --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0054-winegstreamer-Feed-full-buffer-in-audio-converter-Pr.patch b/patches/mfplat-streaming-support/0054-winegstreamer-Feed-full-buffer-in-audio-converter-Pr.patch deleted file mode 100644 index 50980c87..00000000 --- a/patches/mfplat-streaming-support/0054-winegstreamer-Feed-full-buffer-in-audio-converter-Pr.patch +++ /dev/null @@ -1,48 +0,0 @@ -From 78f397bed7e11787011ffdb4dead4ee54a18730f Mon Sep 17 00:00:00 2001 -From: Andrew Eikum -Date: Fri, 7 Jan 2022 10:04:49 -0600 -Subject: [PATCH 54/88] winegstreamer: Feed full buffer in audio converter - ProcessInput - -In push mode, we can ignore the size of the request. wg_parser will -forward the entire buffer to gst. - -CW-Bug-Id: #19859 ---- - dlls/winegstreamer/audioconvert.c | 17 ++++++----------- - 1 file changed, 6 insertions(+), 11 deletions(-) - -diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c -index 28d449e9f9b..58daf388a30 100644 ---- a/dlls/winegstreamer/audioconvert.c -+++ b/dlls/winegstreamer/audioconvert.c -@@ -685,20 +685,15 @@ static HRESULT WINAPI audio_converter_ProcessInput(IMFTransform *iface, DWORD id - if (FAILED(hr = IMFMediaBuffer_Lock(buffer, &buffer_data, NULL, &buffer_size))) - goto done; - -- for (;;) -+ if (!wg_parser_get_next_read_offset(converter->parser, &offset, &size)) - { -- if (!wg_parser_get_next_read_offset(converter->parser, &offset, &size)) -- continue; -- -- wg_parser_push_data(converter->parser, WG_READ_SUCCESS, buffer_data, min(buffer_size, size)); -- -- if (buffer_size <= size) -- break; -- -- buffer_data += size; -- buffer_size -= size; -+ hr = MF_E_UNEXPECTED; -+ IMFMediaBuffer_Unlock(buffer); -+ goto done; - } - -+ wg_parser_push_data(converter->parser, WG_READ_SUCCESS, buffer_data, buffer_size); -+ - IMFMediaBuffer_Unlock(buffer); - converter->buffer_inflight = TRUE; - if (FAILED(IMFSample_GetSampleTime(sample, &converter->buffer_pts))) --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0056-winegstreamer-Return-S_OK-from-WMA-decoder-ProcessMe.patch b/patches/mfplat-streaming-support/0056-winegstreamer-Return-S_OK-from-WMA-decoder-ProcessMe.patch deleted file mode 100644 index 5a7efb23..00000000 --- a/patches/mfplat-streaming-support/0056-winegstreamer-Return-S_OK-from-WMA-decoder-ProcessMe.patch +++ /dev/null @@ -1,29 +0,0 @@ -From c25b5225beb33b0a4403b296e06439c7b8e712b9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Mon, 17 Jan 2022 14:06:43 +0100 -Subject: [PATCH 56/88] winegstreamer: Return S_OK from WMA decoder - ProcessMessage. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51931 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52391 -CW-Bug-Id: #19854 ---- - dlls/winegstreamer/wma_decoder.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c -index 78316059052..847387d3c22 100644 ---- a/dlls/winegstreamer/wma_decoder.c -+++ b/dlls/winegstreamer/wma_decoder.c -@@ -486,7 +486,7 @@ static HRESULT WINAPI transform_ProcessEvent(IMFTransform *iface, DWORD id, IMFM - static HRESULT WINAPI transform_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param) - { - FIXME("iface %p, message %#x, param %p stub!\n", iface, message, (void *)param); -- return E_NOTIMPL; -+ return S_OK; - } - - static HRESULT WINAPI transform_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags) --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0057-winegstreamer-Introduce-new-wg_transform-struct.patch b/patches/mfplat-streaming-support/0057-winegstreamer-Introduce-new-wg_transform-struct.patch deleted file mode 100644 index 2d097431..00000000 --- a/patches/mfplat-streaming-support/0057-winegstreamer-Introduce-new-wg_transform-struct.patch +++ /dev/null @@ -1,326 +0,0 @@ -From ba6442e42f35798a759c625916ad7b58e1672eb0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Wed, 26 Jan 2022 21:24:07 +0100 -Subject: [PATCH 57/88] winegstreamer: Introduce new wg_transform struct. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51931 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52391 -CW-Bug-Id: #19854 ---- - dlls/winegstreamer/Makefile.in | 1 + - dlls/winegstreamer/gst_private.h | 3 ++ - dlls/winegstreamer/main.c | 14 +++++++ - dlls/winegstreamer/unix_private.h | 31 ++++++++++++++ - dlls/winegstreamer/unixlib.h | 8 ++++ - dlls/winegstreamer/wg_parser.c | 20 +++++++-- - dlls/winegstreamer/wg_transform.c | 69 +++++++++++++++++++++++++++++++ - dlls/winegstreamer/wma_decoder.c | 20 +++++++++ - 8 files changed, 162 insertions(+), 4 deletions(-) - create mode 100644 dlls/winegstreamer/unix_private.h - create mode 100644 dlls/winegstreamer/wg_transform.c - -diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in -index 74bcc35364b..294d3b199a5 100644 ---- a/dlls/winegstreamer/Makefile.in -+++ b/dlls/winegstreamer/Makefile.in -@@ -15,6 +15,7 @@ C_SRCS = \ - mfplat.c \ - quartz_parser.c \ - wg_parser.c \ -+ wg_transform.c \ - wm_asyncreader.c \ - wm_reader.c \ - wm_syncreader.c \ -diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h -index f1c7bc60428..416dfae01de 100644 ---- a/dlls/winegstreamer/gst_private.h -+++ b/dlls/winegstreamer/gst_private.h -@@ -100,6 +100,9 @@ void wg_parser_stream_seek(struct wg_parser_stream *stream, double rate, - uint64_t start_pos, uint64_t stop_pos, DWORD start_flags, DWORD stop_flags); - bool wg_parser_stream_drain(struct wg_parser_stream *stream); - -+struct wg_transform *wg_transform_create(void) DECLSPEC_HIDDEN; -+void wg_transform_destroy(struct wg_transform *transform) DECLSPEC_HIDDEN; -+ - unsigned int wg_format_get_max_size(const struct wg_format *format); - - HRESULT avi_splitter_create(IUnknown *outer, IUnknown **out); -diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c -index 74f0dd04e83..6938d111926 100644 ---- a/dlls/winegstreamer/main.c -+++ b/dlls/winegstreamer/main.c -@@ -288,6 +288,20 @@ bool wg_parser_stream_drain(struct wg_parser_stream *stream) - return !__wine_unix_call(unix_handle, unix_wg_parser_stream_drain, stream); - } - -+struct wg_transform *wg_transform_create(void) -+{ -+ struct wg_transform_create_params params = {0}; -+ -+ if (__wine_unix_call(unix_handle, unix_wg_transform_create, ¶ms)) -+ return NULL; -+ return params.transform; -+} -+ -+void wg_transform_destroy(struct wg_transform *transform) -+{ -+ __wine_unix_call(unix_handle, unix_wg_transform_destroy, transform); -+} -+ - BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved) - { - if (reason == DLL_PROCESS_ATTACH) -diff --git a/dlls/winegstreamer/unix_private.h b/dlls/winegstreamer/unix_private.h -new file mode 100644 -index 00000000000..375d33e7728 ---- /dev/null -+++ b/dlls/winegstreamer/unix_private.h -@@ -0,0 +1,31 @@ -+/* -+ * winegstreamer Unix library interface -+ * -+ * Copyright 2020-2021 Zebediah Figura for CodeWeavers -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+#ifndef __WINE_WINEGSTREAMER_UNIX_PRIVATE_H -+#define __WINE_WINEGSTREAMER_UNIX_PRIVATE_H -+ -+#include "unixlib.h" -+ -+extern bool init_gstreamer(void) DECLSPEC_HIDDEN; -+ -+extern NTSTATUS wg_transform_create(void *args) DECLSPEC_HIDDEN; -+extern NTSTATUS wg_transform_destroy(void *args) DECLSPEC_HIDDEN; -+ -+#endif /* __WINE_WINEGSTREAMER_UNIX_PRIVATE_H */ -diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h -index 5946621fb9d..25e130d834a 100644 ---- a/dlls/winegstreamer/unixlib.h -+++ b/dlls/winegstreamer/unixlib.h -@@ -279,6 +279,11 @@ struct wg_parser_stream_seek_params - DWORD start_flags, stop_flags; - }; - -+struct wg_transform_create_params -+{ -+ struct wg_transform *transform; -+}; -+ - enum unix_funcs - { - unix_wg_parser_create, -@@ -310,6 +315,9 @@ enum unix_funcs - unix_wg_parser_stream_get_language, - unix_wg_parser_stream_seek, - -+ unix_wg_transform_create, -+ unix_wg_transform_destroy, -+ - unix_wg_parser_stream_drain, - }; - -diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index 833671df20c..b8662c4417d 100644 ---- a/dlls/winegstreamer/wg_parser.c -+++ b/dlls/winegstreamer/wg_parser.c -@@ -37,7 +37,7 @@ - #include "winternl.h" - #include "dshow.h" - --#include "unixlib.h" -+#include "unix_private.h" - - typedef enum - { -@@ -51,7 +51,7 @@ typedef enum - * debug logging instead of Wine debug logging. In order to be safe we forbid - * any use of Wine debug logging in this entire file. */ - --GST_DEBUG_CATEGORY_STATIC(wine); -+GST_DEBUG_CATEGORY(wine); - #define GST_CAT_DEFAULT wine - - typedef BOOL (*init_gst_cb)(struct wg_parser *parser); -@@ -2569,6 +2569,16 @@ static void init_gstreamer_once(void) - gst_version_string(), GST_VERSION_MAJOR, GST_VERSION_MINOR, GST_VERSION_MICRO); - } - -+bool init_gstreamer(void) -+{ -+ static pthread_once_t init_once = PTHREAD_ONCE_INIT; -+ -+ if (pthread_once(&init_once, init_gstreamer_once)) -+ return false; -+ -+ return true; -+} -+ - static NTSTATUS wg_parser_create(void *args) - { - static const init_gst_cb init_funcs[] = -@@ -2581,11 +2591,10 @@ static NTSTATUS wg_parser_create(void *args) - [WG_PARSER_VIDEOCONV] = video_convert_init_gst, - }; - -- static pthread_once_t once = PTHREAD_ONCE_INIT; - struct wg_parser_create_params *params = args; - struct wg_parser *parser; - -- if (pthread_once(&once, init_gstreamer_once)) -+ if (!init_gstreamer()) - return E_FAIL; - - if (!(parser = calloc(1, sizeof(*parser)))) -@@ -2655,5 +2664,8 @@ const unixlib_entry_t __wine_unix_call_funcs[] = - X(wg_parser_stream_get_language), - X(wg_parser_stream_seek), - -+ X(wg_transform_create), -+ X(wg_transform_destroy), -+ - X(wg_parser_stream_drain), - }; -diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c -new file mode 100644 -index 00000000000..822740da0d7 ---- /dev/null -+++ b/dlls/winegstreamer/wg_transform.c -@@ -0,0 +1,69 @@ -+/* -+ * GStreamer transform backend -+ * -+ * Copyright 2022 RĂ©mi Bernon for CodeWeavers -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+#if 0 -+#pragma makedep unix -+#endif -+ -+#include "config.h" -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "winternl.h" -+#include "dshow.h" -+ -+#include "unix_private.h" -+ -+GST_DEBUG_CATEGORY_EXTERN(wine); -+#define GST_CAT_DEFAULT wine -+ -+struct wg_transform -+{ -+}; -+ -+NTSTATUS wg_transform_destroy(void *args) -+{ -+ struct wg_transform *transform = args; -+ -+ free(transform); -+ return S_OK; -+} -+ -+NTSTATUS wg_transform_create(void *args) -+{ -+ struct wg_transform_create_params *params = args; -+ struct wg_transform *transform; -+ -+ if (!init_gstreamer()) -+ return E_FAIL; -+ -+ if (!(transform = calloc(1, sizeof(*transform)))) -+ return E_OUTOFMEMORY; -+ -+ GST_INFO("Created winegstreamer transform %p.", transform); -+ params->transform = transform; -+ return S_OK; -+} -diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c -index 847387d3c22..1544e8e4c9b 100644 ---- a/dlls/winegstreamer/wma_decoder.c -+++ b/dlls/winegstreamer/wma_decoder.c -@@ -53,6 +53,8 @@ struct wma_decoder - LONG refcount; - IMFMediaType *input_type; - IMFMediaType *output_type; -+ -+ struct wg_transform *wg_transform; - }; - - static inline struct wma_decoder *impl_from_IUnknown(IUnknown *iface) -@@ -60,6 +62,19 @@ static inline struct wma_decoder *impl_from_IUnknown(IUnknown *iface) - return CONTAINING_RECORD(iface, struct wma_decoder, IUnknown_inner); - } - -+static HRESULT try_create_wg_transform(struct wma_decoder *decoder) -+{ -+ if (decoder->wg_transform) -+ wg_transform_destroy(decoder->wg_transform); -+ -+ decoder->wg_transform = wg_transform_create(); -+ if (decoder->wg_transform) -+ return S_OK; -+ -+ WARN("Failed to create wg_transform.\n"); -+ return E_FAIL; -+} -+ - static HRESULT WINAPI unknown_QueryInterface(IUnknown *iface, REFIID iid, void **out) - { - struct wma_decoder *decoder = impl_from_IUnknown(iface); -@@ -104,6 +119,8 @@ static ULONG WINAPI unknown_Release(IUnknown *iface) - - if (!refcount) - { -+ if (decoder->wg_transform) -+ wg_transform_destroy(decoder->wg_transform); - if (decoder->input_type) - IMFMediaType_Release(decoder->input_type); - if (decoder->output_type) -@@ -438,6 +455,9 @@ static HRESULT WINAPI transform_SetOutputType(IMFTransform *iface, DWORD id, IMF - if (FAILED(hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *)decoder->output_type))) - goto failed; - -+ if (FAILED(hr = try_create_wg_transform(decoder))) -+ goto failed; -+ - return S_OK; - - failed: --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0058-winegstreamer-Introduce-new-wg_encoded_format-struct.patch b/patches/mfplat-streaming-support/0058-winegstreamer-Introduce-new-wg_encoded_format-struct.patch deleted file mode 100644 index 8e9a0812..00000000 --- a/patches/mfplat-streaming-support/0058-winegstreamer-Introduce-new-wg_encoded_format-struct.patch +++ /dev/null @@ -1,185 +0,0 @@ -From 19ae522a9a7170b0d07a1f6810858020cd9d9f1e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Fri, 21 Jan 2022 14:02:52 +0100 -Subject: [PATCH 58/88] winegstreamer: Introduce new wg_encoded_format struct. - -And use it for decoder transform input types. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51931 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52391 -CW-Bug-Id: #19854 ---- - dlls/winegstreamer/gst_private.h | 1 + - dlls/winegstreamer/mfplat.c | 84 ++++++++++++++++++++++++++++++++ - dlls/winegstreamer/unixlib.h | 25 ++++++++++ - dlls/winegstreamer/wma_decoder.c | 12 +++++ - 4 files changed, 122 insertions(+) - -diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h -index 416dfae01de..551dcc549c7 100644 ---- a/dlls/winegstreamer/gst_private.h -+++ b/dlls/winegstreamer/gst_private.h -@@ -121,6 +121,7 @@ extern HRESULT mfplat_DllRegisterServer(void); - - IMFMediaType *mf_media_type_from_wg_format(const struct wg_format *format); - void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format); -+void mf_media_type_to_wg_encoded_format(IMFMediaType *type, struct wg_encoded_format *format); - - HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj); - -diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index 54874ad43ee..ca64ce3f7b9 100644 ---- a/dlls/winegstreamer/mfplat.c -+++ b/dlls/winegstreamer/mfplat.c -@@ -892,3 +892,87 @@ void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format) - else - FIXME("Unrecognized major type %s.\n", debugstr_guid(&major_type)); - } -+ -+static void mf_media_type_to_wg_encoded_format_wma(IMFMediaType *type, struct wg_encoded_format *format, -+ UINT32 version) -+{ -+ UINT32 rate, depth, channels, block_align, bytes_per_second, codec_data_len; -+ BYTE codec_data[64]; -+ -+ if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &rate))) -+ { -+ FIXME("Sample rate is not set.\n"); -+ return; -+ } -+ if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &channels))) -+ { -+ FIXME("Channel count is not set.\n"); -+ return; -+ } -+ if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &block_align))) -+ { -+ FIXME("Block alignment is not set.\n"); -+ return; -+ } -+ if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &depth))) -+ { -+ FIXME("Depth is not set.\n"); -+ return; -+ } -+ if (FAILED(IMFMediaType_GetBlob(type, &MF_MT_USER_DATA, codec_data, sizeof(codec_data), &codec_data_len))) -+ { -+ FIXME("Codec data is not set.\n"); -+ return; -+ } -+ if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &bytes_per_second))) -+ { -+ FIXME("Bitrate is not set.\n"); -+ bytes_per_second = 0; -+ } -+ -+ format->encoded_type = WG_ENCODED_TYPE_WMA; -+ format->u.xwma.version = version; -+ format->u.xwma.bitrate = bytes_per_second * 8; -+ format->u.xwma.rate = rate; -+ format->u.xwma.depth = depth; -+ format->u.xwma.channels = channels; -+ format->u.xwma.block_align = block_align; -+ format->u.xwma.codec_data_len = codec_data_len; -+ memcpy(format->u.xwma.codec_data, codec_data, codec_data_len); -+} -+ -+void mf_media_type_to_wg_encoded_format(IMFMediaType *type, struct wg_encoded_format *format) -+{ -+ GUID major_type, subtype; -+ -+ memset(format, 0, sizeof(*format)); -+ -+ if (FAILED(IMFMediaType_GetMajorType(type, &major_type))) -+ { -+ FIXME("Major type is not set.\n"); -+ return; -+ } -+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype))) -+ { -+ FIXME("Subtype is not set.\n"); -+ return; -+ } -+ -+ if (IsEqualGUID(&major_type, &MFMediaType_Audio)) -+ { -+ if (IsEqualGUID(&subtype, &MEDIASUBTYPE_MSAUDIO1)) -+ mf_media_type_to_wg_encoded_format_wma(type, format, 1); -+ else if (IsEqualGUID(&subtype, &MFAudioFormat_WMAudioV8)) -+ mf_media_type_to_wg_encoded_format_wma(type, format, 2); -+ else if (IsEqualGUID(&subtype, &MFAudioFormat_WMAudioV9)) -+ mf_media_type_to_wg_encoded_format_wma(type, format, 3); -+ else if (IsEqualGUID(&subtype, &MFAudioFormat_WMAudio_Lossless)) -+ mf_media_type_to_wg_encoded_format_wma(type, format, 4); -+ else -+ FIXME("Unimplemented audio subtype %s.\n", debugstr_guid(&subtype)); -+ } -+ else -+ { -+ FIXME("Unimplemented major type %s.\n", debugstr_guid(&major_type)); -+ } -+} -diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h -index 25e130d834a..7d3eceb6a51 100644 ---- a/dlls/winegstreamer/unixlib.h -+++ b/dlls/winegstreamer/unixlib.h -@@ -125,6 +125,31 @@ struct wg_rect - uint32_t bottom; - }; - -+struct wg_encoded_format -+{ -+ enum wg_encoded_type -+ { -+ WG_ENCODED_TYPE_UNKNOWN, -+ WG_ENCODED_TYPE_WMA, -+ WG_ENCODED_TYPE_XMA, -+ } encoded_type; -+ -+ union -+ { -+ struct -+ { -+ uint32_t version; -+ uint32_t bitrate; -+ uint32_t rate; -+ uint32_t depth; -+ uint32_t channels; -+ uint32_t block_align; -+ uint32_t codec_data_len; -+ unsigned char codec_data[64]; -+ } xwma; -+ } u; -+}; -+ - enum wg_parser_event_type - { - WG_PARSER_EVENT_NONE = 0, -diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c -index 1544e8e4c9b..2b543426524 100644 ---- a/dlls/winegstreamer/wma_decoder.c -+++ b/dlls/winegstreamer/wma_decoder.c -@@ -64,8 +64,20 @@ static inline struct wma_decoder *impl_from_IUnknown(IUnknown *iface) - - static HRESULT try_create_wg_transform(struct wma_decoder *decoder) - { -+ struct wg_encoded_format input_format; -+ struct wg_format output_format; -+ - if (decoder->wg_transform) - wg_transform_destroy(decoder->wg_transform); -+ decoder->wg_transform = NULL; -+ -+ mf_media_type_to_wg_encoded_format(decoder->input_type, &input_format); -+ if (input_format.encoded_type == WG_ENCODED_TYPE_UNKNOWN) -+ return MF_E_INVALIDMEDIATYPE; -+ -+ mf_media_type_to_wg_format(decoder->output_type, &output_format); -+ if (output_format.major_type == WG_MAJOR_TYPE_UNKNOWN) -+ return MF_E_INVALIDMEDIATYPE; - - decoder->wg_transform = wg_transform_create(); - if (decoder->wg_transform) --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0059-winegstreamer-Create-static-pads-on-wg_transform-str.patch b/patches/mfplat-streaming-support/0059-winegstreamer-Create-static-pads-on-wg_transform-str.patch deleted file mode 100644 index a391cacf..00000000 --- a/patches/mfplat-streaming-support/0059-winegstreamer-Create-static-pads-on-wg_transform-str.patch +++ /dev/null @@ -1,236 +0,0 @@ -From 1f48e9be35754d7197b77711dc86ef0033eb381b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Fri, 21 Jan 2022 14:22:59 +0100 -Subject: [PATCH 59/88] winegstreamer: Create static pads on wg_transform - struct. - -With caps created from the input / output formats. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51931 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52391 -CW-Bug-Id: #19854 ---- - dlls/winegstreamer/gst_private.h | 3 +- - dlls/winegstreamer/main.c | 9 ++- - dlls/winegstreamer/unix_private.h | 1 + - dlls/winegstreamer/unixlib.h | 2 + - dlls/winegstreamer/wg_parser.c | 2 +- - dlls/winegstreamer/wg_transform.c | 93 +++++++++++++++++++++++++++++++ - dlls/winegstreamer/wma_decoder.c | 2 +- - 7 files changed, 107 insertions(+), 5 deletions(-) - -diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h -index 551dcc549c7..6432ae37fc0 100644 ---- a/dlls/winegstreamer/gst_private.h -+++ b/dlls/winegstreamer/gst_private.h -@@ -100,7 +100,8 @@ void wg_parser_stream_seek(struct wg_parser_stream *stream, double rate, - uint64_t start_pos, uint64_t stop_pos, DWORD start_flags, DWORD stop_flags); - bool wg_parser_stream_drain(struct wg_parser_stream *stream); - --struct wg_transform *wg_transform_create(void) DECLSPEC_HIDDEN; -+struct wg_transform *wg_transform_create(const struct wg_encoded_format *input_format, -+ const struct wg_format *output_format) DECLSPEC_HIDDEN; - void wg_transform_destroy(struct wg_transform *transform) DECLSPEC_HIDDEN; - - unsigned int wg_format_get_max_size(const struct wg_format *format); -diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c -index 6938d111926..d3e87973fdf 100644 ---- a/dlls/winegstreamer/main.c -+++ b/dlls/winegstreamer/main.c -@@ -288,9 +288,14 @@ bool wg_parser_stream_drain(struct wg_parser_stream *stream) - return !__wine_unix_call(unix_handle, unix_wg_parser_stream_drain, stream); - } - --struct wg_transform *wg_transform_create(void) -+struct wg_transform *wg_transform_create(const struct wg_encoded_format *input_format, -+ const struct wg_format *output_format) - { -- struct wg_transform_create_params params = {0}; -+ struct wg_transform_create_params params = -+ { -+ .input_format = input_format, -+ .output_format = output_format, -+ }; - - if (__wine_unix_call(unix_handle, unix_wg_transform_create, ¶ms)) - return NULL; -diff --git a/dlls/winegstreamer/unix_private.h b/dlls/winegstreamer/unix_private.h -index 375d33e7728..38349eb5e8d 100644 ---- a/dlls/winegstreamer/unix_private.h -+++ b/dlls/winegstreamer/unix_private.h -@@ -24,6 +24,7 @@ - #include "unixlib.h" - - extern bool init_gstreamer(void) DECLSPEC_HIDDEN; -+extern GstCaps *wg_format_to_caps(const struct wg_format *format) DECLSPEC_HIDDEN; - - extern NTSTATUS wg_transform_create(void *args) DECLSPEC_HIDDEN; - extern NTSTATUS wg_transform_destroy(void *args) DECLSPEC_HIDDEN; -diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h -index 7d3eceb6a51..51ffc5d3efe 100644 ---- a/dlls/winegstreamer/unixlib.h -+++ b/dlls/winegstreamer/unixlib.h -@@ -307,6 +307,8 @@ struct wg_parser_stream_seek_params - struct wg_transform_create_params - { - struct wg_transform *transform; -+ const struct wg_encoded_format *input_format; -+ const struct wg_format *output_format; - }; - - enum unix_funcs -diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index b8662c4417d..2970e2464a2 100644 ---- a/dlls/winegstreamer/wg_parser.c -+++ b/dlls/winegstreamer/wg_parser.c -@@ -541,7 +541,7 @@ static GstCaps *wg_format_to_caps_video(const struct wg_format *format) - return caps; - } - --static GstCaps *wg_format_to_caps(const struct wg_format *format) -+GstCaps *wg_format_to_caps(const struct wg_format *format) - { - switch (format->major_type) - { -diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c -index 822740da0d7..146cdd87ae7 100644 ---- a/dlls/winegstreamer/wg_transform.c -+++ b/dlls/winegstreamer/wg_transform.c -@@ -42,12 +42,77 @@ GST_DEBUG_CATEGORY_EXTERN(wine); - - struct wg_transform - { -+ GstPad *my_src, *my_sink; - }; - -+static GstCaps *wg_format_to_caps_xwma(const struct wg_encoded_format *format) -+{ -+ GstBuffer *buffer; -+ GstCaps *caps; -+ -+ if (format->encoded_type == WG_ENCODED_TYPE_WMA) -+ caps = gst_caps_new_empty_simple("audio/x-wma"); -+ else -+ caps = gst_caps_new_empty_simple("audio/x-xma"); -+ -+ if (format->u.xwma.version) -+ gst_caps_set_simple(caps, "wmaversion", G_TYPE_INT, format->u.xwma.version, NULL); -+ if (format->u.xwma.bitrate) -+ gst_caps_set_simple(caps, "bitrate", G_TYPE_INT, format->u.xwma.bitrate, NULL); -+ if (format->u.xwma.rate) -+ gst_caps_set_simple(caps, "rate", G_TYPE_INT, format->u.xwma.rate, NULL); -+ if (format->u.xwma.depth) -+ gst_caps_set_simple(caps, "depth", G_TYPE_INT, format->u.xwma.depth, NULL); -+ if (format->u.xwma.channels) -+ gst_caps_set_simple(caps, "channels", G_TYPE_INT, format->u.xwma.channels, NULL); -+ if (format->u.xwma.block_align) -+ gst_caps_set_simple(caps, "block_align", G_TYPE_INT, format->u.xwma.block_align, NULL); -+ -+ if (format->u.xwma.codec_data_len) -+ { -+ buffer = gst_buffer_new_and_alloc(format->u.xwma.codec_data_len); -+ gst_buffer_fill(buffer, 0, format->u.xwma.codec_data, format->u.xwma.codec_data_len); -+ gst_caps_set_simple(caps, "codec_data", GST_TYPE_BUFFER, buffer, NULL); -+ gst_buffer_unref(buffer); -+ } -+ -+ return caps; -+} -+ -+static GstCaps *wg_encoded_format_to_caps(const struct wg_encoded_format *format) -+{ -+ switch (format->encoded_type) -+ { -+ case WG_ENCODED_TYPE_UNKNOWN: -+ return NULL; -+ case WG_ENCODED_TYPE_WMA: -+ case WG_ENCODED_TYPE_XMA: -+ return wg_format_to_caps_xwma(format); -+ } -+ assert(0); -+ return NULL; -+} -+ -+static GstFlowReturn transform_sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *buffer) -+{ -+ struct wg_transform *transform = gst_pad_get_element_private(pad); -+ -+ GST_INFO("transform %p, buffer %p.", transform, buffer); -+ -+ gst_buffer_unref(buffer); -+ -+ return GST_FLOW_OK; -+} -+ - NTSTATUS wg_transform_destroy(void *args) - { - struct wg_transform *transform = args; - -+ if (transform->my_sink) -+ g_object_unref(transform->my_sink); -+ if (transform->my_src) -+ g_object_unref(transform->my_src); -+ - free(transform); - return S_OK; - } -@@ -55,7 +120,11 @@ NTSTATUS wg_transform_destroy(void *args) - NTSTATUS wg_transform_create(void *args) - { - struct wg_transform_create_params *params = args; -+ struct wg_encoded_format input_format = *params->input_format; -+ struct wg_format output_format = *params->output_format; -+ GstCaps *src_caps, *sink_caps; - struct wg_transform *transform; -+ GstPadTemplate *template; - - if (!init_gstreamer()) - return E_FAIL; -@@ -63,7 +132,31 @@ NTSTATUS wg_transform_create(void *args) - if (!(transform = calloc(1, sizeof(*transform)))) - return E_OUTOFMEMORY; - -+ src_caps = wg_encoded_format_to_caps(&input_format); -+ assert(src_caps); -+ sink_caps = wg_format_to_caps(&output_format); -+ assert(sink_caps); -+ -+ template = gst_pad_template_new("src", GST_PAD_SRC, GST_PAD_ALWAYS, src_caps); -+ assert(template); -+ transform->my_src = gst_pad_new_from_template(template, "src"); -+ g_object_unref(template); -+ assert(transform->my_src); -+ -+ template = gst_pad_template_new("sink", GST_PAD_SINK, GST_PAD_ALWAYS, sink_caps); -+ assert(template); -+ transform->my_sink = gst_pad_new_from_template(template, "sink"); -+ g_object_unref(template); -+ assert(transform->my_sink); -+ -+ gst_pad_set_element_private(transform->my_sink, transform); -+ gst_pad_set_chain_function(transform->my_sink, transform_sink_chain_cb); -+ - GST_INFO("Created winegstreamer transform %p.", transform); - params->transform = transform; -+ -+ gst_caps_unref(src_caps); -+ gst_caps_unref(sink_caps); -+ - return S_OK; - } -diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c -index 2b543426524..db6c8a677f6 100644 ---- a/dlls/winegstreamer/wma_decoder.c -+++ b/dlls/winegstreamer/wma_decoder.c -@@ -79,7 +79,7 @@ static HRESULT try_create_wg_transform(struct wma_decoder *decoder) - if (output_format.major_type == WG_MAJOR_TYPE_UNKNOWN) - return MF_E_INVALIDMEDIATYPE; - -- decoder->wg_transform = wg_transform_create(); -+ decoder->wg_transform = wg_transform_create(&input_format, &output_format); - if (decoder->wg_transform) - return S_OK; - --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0060-winegstreamer-Lookup-create-and-link-a-decoder-eleme.patch b/patches/mfplat-streaming-support/0060-winegstreamer-Lookup-create-and-link-a-decoder-eleme.patch deleted file mode 100644 index 96cfdb98..00000000 --- a/patches/mfplat-streaming-support/0060-winegstreamer-Lookup-create-and-link-a-decoder-eleme.patch +++ /dev/null @@ -1,207 +0,0 @@ -From 855ce2096c36de51d227cb07a88a73e51c34d3a9 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Fri, 21 Jan 2022 14:24:27 +0100 -Subject: [PATCH 60/88] winegstreamer: Lookup, create and link a decoder - element. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51931 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52391 -CW-Bug-Id: #19854 ---- - dlls/winegstreamer/wg_transform.c | 140 +++++++++++++++++++++++++++++- - 1 file changed, 138 insertions(+), 2 deletions(-) - -diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c -index 146cdd87ae7..a436d8316dd 100644 ---- a/dlls/winegstreamer/wg_transform.c -+++ b/dlls/winegstreamer/wg_transform.c -@@ -42,7 +42,9 @@ GST_DEBUG_CATEGORY_EXTERN(wine); - - struct wg_transform - { -+ GstElement *container; - GstPad *my_src, *my_sink; -+ GstPad *their_sink, *their_src; - }; - - static GstCaps *wg_format_to_caps_xwma(const struct wg_encoded_format *format) -@@ -108,6 +110,22 @@ NTSTATUS wg_transform_destroy(void *args) - { - struct wg_transform *transform = args; - -+ if (transform->container) -+ gst_element_set_state(transform->container, GST_STATE_NULL); -+ -+ if (transform->their_src && transform->my_sink) -+ gst_pad_unlink(transform->their_src, transform->my_sink); -+ if (transform->their_sink && transform->my_src) -+ gst_pad_unlink(transform->my_src, transform->their_sink); -+ -+ if (transform->their_sink) -+ g_object_unref(transform->their_sink); -+ if (transform->their_src) -+ g_object_unref(transform->their_src); -+ -+ if (transform->container) -+ g_object_unref(transform->container); -+ - if (transform->my_sink) - g_object_unref(transform->my_sink); - if (transform->my_src) -@@ -117,14 +135,85 @@ NTSTATUS wg_transform_destroy(void *args) - return S_OK; - } - -+static GstElement *try_create_transform(GstCaps *src_caps, GstCaps *sink_caps) -+{ -+ GstElement *element = NULL; -+ GList *tmp, *transforms; -+ gchar *type; -+ -+ transforms = gst_element_factory_list_get_elements(GST_ELEMENT_FACTORY_TYPE_ANY, -+ GST_RANK_MARGINAL); -+ -+ tmp = gst_element_factory_list_filter(transforms, src_caps, GST_PAD_SINK, FALSE); -+ gst_plugin_feature_list_free(transforms); -+ transforms = tmp; -+ -+ tmp = gst_element_factory_list_filter(transforms, sink_caps, GST_PAD_SRC, FALSE); -+ gst_plugin_feature_list_free(transforms); -+ transforms = tmp; -+ -+ transforms = g_list_sort(transforms, gst_plugin_feature_rank_compare_func); -+ for (tmp = transforms; tmp != NULL && element == NULL; tmp = tmp->next) -+ { -+ type = gst_plugin_feature_get_name(GST_PLUGIN_FEATURE(tmp->data)); -+ element = gst_element_factory_create(GST_ELEMENT_FACTORY(tmp->data), NULL); -+ if (!element) -+ GST_WARNING("Failed to create %s element.", type); -+ } -+ gst_plugin_feature_list_free(transforms); -+ -+ if (element) -+ GST_INFO("Created %s element %p.", type, element); -+ else -+ { -+ gchar *src_str = gst_caps_to_string(src_caps), *sink_str = gst_caps_to_string(sink_caps); -+ GST_WARNING("Failed to create transform matching caps %s / %s.", src_str, sink_str); -+ g_free(sink_str); -+ g_free(src_str); -+ } -+ -+ return element; -+} -+ -+static bool transform_append_element(struct wg_transform *transform, GstElement *element, -+ GstElement **first, GstElement **last) -+{ -+ gchar *name = gst_element_get_name(element); -+ -+ if (!gst_bin_add(GST_BIN(transform->container), element)) -+ { -+ GST_ERROR("Failed to add %s element to bin.", name); -+ g_free(name); -+ return false; -+ } -+ -+ if (*last && !gst_element_link(*last, element)) -+ { -+ GST_ERROR("Failed to link %s element.", name); -+ g_free(name); -+ return false; -+ } -+ -+ GST_INFO("Created %s element %p.", name, element); -+ g_free(name); -+ -+ if (!*first) -+ *first = element; -+ -+ *last = element; -+ return true; -+} -+ - NTSTATUS wg_transform_create(void *args) - { - struct wg_transform_create_params *params = args; - struct wg_encoded_format input_format = *params->input_format; - struct wg_format output_format = *params->output_format; -- GstCaps *src_caps, *sink_caps; -+ GstElement *first = NULL, *last = NULL, *element; - struct wg_transform *transform; -+ GstCaps *src_caps, *sink_caps; - GstPadTemplate *template; -+ int ret; - - if (!init_gstreamer()) - return E_FAIL; -@@ -137,6 +226,24 @@ NTSTATUS wg_transform_create(void *args) - sink_caps = wg_format_to_caps(&output_format); - assert(sink_caps); - -+ transform->container = gst_bin_new("wg_transform"); -+ assert(transform->container); -+ -+ if (!(element = try_create_transform(src_caps, sink_caps)) || -+ !transform_append_element(transform, element, &first, &last)) -+ goto failed; -+ -+ if (!(transform->their_sink = gst_element_get_static_pad(first, "sink"))) -+ { -+ GST_ERROR("Failed to find target sink pad."); -+ goto failed; -+ } -+ if (!(transform->their_src = gst_element_get_static_pad(last, "src"))) -+ { -+ GST_ERROR("Failed to find target src pad."); -+ goto failed; -+ } -+ - template = gst_pad_template_new("src", GST_PAD_SRC, GST_PAD_ALWAYS, src_caps); - assert(template); - transform->my_src = gst_pad_new_from_template(template, "src"); -@@ -152,11 +259,40 @@ NTSTATUS wg_transform_create(void *args) - gst_pad_set_element_private(transform->my_sink, transform); - gst_pad_set_chain_function(transform->my_sink, transform_sink_chain_cb); - -+ if ((ret = gst_pad_link(transform->my_src, transform->their_sink)) < 0) -+ { -+ GST_ERROR("Failed to link sink pads, error %d.", ret); -+ goto failed; -+ } -+ if ((ret = gst_pad_link(transform->their_src, transform->my_sink)) < 0) -+ { -+ GST_ERROR("Failed to link source pads, error %d.", ret); -+ goto failed; -+ } -+ -+ if (!(ret = gst_pad_set_active(transform->my_sink, 1))) -+ GST_WARNING("Failed to activate my_sink."); -+ if (!(ret = gst_pad_set_active(transform->my_src, 1))) -+ GST_WARNING("Failed to activate my_src."); -+ -+ gst_element_set_state(transform->container, GST_STATE_PAUSED); -+ ret = gst_element_get_state(transform->container, NULL, NULL, -1); -+ if (ret == GST_STATE_CHANGE_FAILURE) -+ { -+ GST_ERROR("Failed to play stream.\n"); -+ goto failed; -+ } -+ - GST_INFO("Created winegstreamer transform %p.", transform); - params->transform = transform; - -+failed: - gst_caps_unref(src_caps); - gst_caps_unref(sink_caps); - -- return S_OK; -+ if (params->transform) -+ return S_OK; -+ -+ wg_transform_destroy(transform); -+ return E_FAIL; - } --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0061-winegstreamer-Send-stream-start-and-caps-events-on-c.patch b/patches/mfplat-streaming-support/0061-winegstreamer-Send-stream-start-and-caps-events-on-c.patch deleted file mode 100644 index 67c5aed4..00000000 --- a/patches/mfplat-streaming-support/0061-winegstreamer-Send-stream-start-and-caps-events-on-c.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 6cc21e8ca6164debd05e7a98b7c20cc65714518b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Fri, 21 Jan 2022 14:25:20 +0100 -Subject: [PATCH 61/88] winegstreamer: Send stream-start and caps events on - creation. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51931 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52391 -CW-Bug-Id: #19854 ---- - dlls/winegstreamer/wg_transform.c | 25 +++++++++++++++++++++++++ - 1 file changed, 25 insertions(+) - -diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c -index a436d8316dd..d87b8cfa2c4 100644 ---- a/dlls/winegstreamer/wg_transform.c -+++ b/dlls/winegstreamer/wg_transform.c -@@ -213,6 +213,7 @@ NTSTATUS wg_transform_create(void *args) - struct wg_transform *transform; - GstCaps *src_caps, *sink_caps; - GstPadTemplate *template; -+ GstSegment *segment; - int ret; - - if (!init_gstreamer()) -@@ -283,6 +284,30 @@ NTSTATUS wg_transform_create(void *args) - goto failed; - } - -+ if (!gst_pad_push_event(transform->my_src, gst_event_new_stream_start("stream"))) -+ { -+ GST_ERROR("Failed to send stream-start."); -+ goto failed; -+ } -+ -+ if (!gst_pad_push_event(transform->my_src, gst_event_new_caps(src_caps))) -+ { -+ GST_ERROR("Failed to set stream caps."); -+ goto failed; -+ } -+ -+ segment = gst_segment_new(); -+ gst_segment_init(segment, GST_FORMAT_TIME); -+ segment->start = 0; -+ segment->stop = -1; -+ ret = gst_pad_push_event(transform->my_src, gst_event_new_segment(segment)); -+ gst_segment_free(segment); -+ if (!ret) -+ { -+ GST_ERROR("Failed to start new segment."); -+ goto failed; -+ } -+ - GST_INFO("Created winegstreamer transform %p.", transform); - params->transform = transform; - --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0062-winegstreamer-Add-an-audioconverter-and-audioresampl.patch b/patches/mfplat-streaming-support/0062-winegstreamer-Add-an-audioconverter-and-audioresampl.patch deleted file mode 100644 index 98016f55..00000000 --- a/patches/mfplat-streaming-support/0062-winegstreamer-Add-an-audioconverter-and-audioresampl.patch +++ /dev/null @@ -1,100 +0,0 @@ -From b90b4207c326a3faf0e6ff5fb0649bd8a081fab7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Fri, 21 Jan 2022 14:25:58 +0100 -Subject: [PATCH 62/88] winegstreamer: Add an audioconverter and audioresampler - elements. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51931 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52391 -CW-Bug-Id: #19854 ---- - dlls/winegstreamer/unix_private.h | 1 + - dlls/winegstreamer/wg_parser.c | 2 +- - dlls/winegstreamer/wg_transform.c | 23 +++++++++++++++++++++-- - 3 files changed, 23 insertions(+), 3 deletions(-) - -diff --git a/dlls/winegstreamer/unix_private.h b/dlls/winegstreamer/unix_private.h -index 38349eb5e8d..e6b0f3636f7 100644 ---- a/dlls/winegstreamer/unix_private.h -+++ b/dlls/winegstreamer/unix_private.h -@@ -24,6 +24,7 @@ - #include "unixlib.h" - - extern bool init_gstreamer(void) DECLSPEC_HIDDEN; -+extern GstElement *create_element(const char *name, const char *plugin_set) DECLSPEC_HIDDEN; - extern GstCaps *wg_format_to_caps(const struct wg_format *format) DECLSPEC_HIDDEN; - - extern NTSTATUS wg_transform_create(void *args) DECLSPEC_HIDDEN; -diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index 2970e2464a2..02bf639962f 100644 ---- a/dlls/winegstreamer/wg_parser.c -+++ b/dlls/winegstreamer/wg_parser.c -@@ -1280,7 +1280,7 @@ static gboolean sink_query_cb(GstPad *pad, GstObject *parent, GstQuery *query) - } - } - --static GstElement *create_element(const char *name, const char *plugin_set) -+GstElement *create_element(const char *name, const char *plugin_set) - { - GstElement *element; - -diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c -index d87b8cfa2c4..d96923594e2 100644 ---- a/dlls/winegstreamer/wg_transform.c -+++ b/dlls/winegstreamer/wg_transform.c -@@ -210,9 +210,10 @@ NTSTATUS wg_transform_create(void *args) - struct wg_encoded_format input_format = *params->input_format; - struct wg_format output_format = *params->output_format; - GstElement *first = NULL, *last = NULL, *element; -+ GstCaps *raw_caps, *src_caps, *sink_caps; - struct wg_transform *transform; -- GstCaps *src_caps, *sink_caps; - GstPadTemplate *template; -+ const gchar *media_type; - GstSegment *segment; - int ret; - -@@ -226,14 +227,31 @@ NTSTATUS wg_transform_create(void *args) - assert(src_caps); - sink_caps = wg_format_to_caps(&output_format); - assert(sink_caps); -+ media_type = gst_structure_get_name(gst_caps_get_structure(sink_caps, 0)); -+ raw_caps = gst_caps_new_empty_simple(media_type); -+ assert(raw_caps); - - transform->container = gst_bin_new("wg_transform"); - assert(transform->container); - -- if (!(element = try_create_transform(src_caps, sink_caps)) || -+ if (!(element = try_create_transform(src_caps, raw_caps)) || - !transform_append_element(transform, element, &first, &last)) - goto failed; - -+ switch (output_format.major_type) -+ { -+ case WG_MAJOR_TYPE_AUDIO: -+ if (!(element = create_element("audioconvert", "base")) || -+ !transform_append_element(transform, element, &first, &last)) -+ goto failed; -+ if (!(element = create_element("audioresample", "base")) || -+ !transform_append_element(transform, element, &first, &last)) -+ goto failed; -+ break; -+ default: -+ break; -+ } -+ - if (!(transform->their_sink = gst_element_get_static_pad(first, "sink"))) - { - GST_ERROR("Failed to find target sink pad."); -@@ -312,6 +330,7 @@ NTSTATUS wg_transform_create(void *args) - params->transform = transform; - - failed: -+ gst_caps_unref(raw_caps); - gst_caps_unref(src_caps); - gst_caps_unref(sink_caps); - --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0063-winegstreamer-Implement-WMA-decoder-ProcessInput.patch b/patches/mfplat-streaming-support/0063-winegstreamer-Implement-WMA-decoder-ProcessInput.patch deleted file mode 100644 index 41f3f4f3..00000000 --- a/patches/mfplat-streaming-support/0063-winegstreamer-Implement-WMA-decoder-ProcessInput.patch +++ /dev/null @@ -1,249 +0,0 @@ -From cd2746f22bdea18808282efbdfa6e599c5b7a5d7 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Fri, 21 Jan 2022 14:28:54 +0100 -Subject: [PATCH 63/88] winegstreamer: Implement WMA decoder ProcessInput. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51931 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52391 -CW-Bug-Id: #19854 ---- - dlls/mf/tests/mf.c | 6 ----- - dlls/winegstreamer/gst_private.h | 1 + - dlls/winegstreamer/main.c | 12 +++++++++ - dlls/winegstreamer/unix_private.h | 1 + - dlls/winegstreamer/unixlib.h | 9 +++++++ - dlls/winegstreamer/wg_parser.c | 2 ++ - dlls/winegstreamer/wg_transform.c | 22 ++++++++++++++++ - dlls/winegstreamer/wma_decoder.c | 43 +++++++++++++++++++++++++++++-- - 8 files changed, 88 insertions(+), 8 deletions(-) - -diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c -index 07f4c28052d..d78f0051714 100644 ---- a/dlls/mf/tests/mf.c -+++ b/dlls/mf/tests/mf.c -@@ -6207,25 +6207,20 @@ static void test_wma_decoder(void) - - sample = create_sample(wma_encoded_data, wma_block_size / 2); - hr = IMFTransform_ProcessInput(transform, 0, sample, 0); -- todo_wine - ok(hr == S_OK, "ProcessInput returned %#x\n", hr); - ret = IMFSample_Release(sample); - ok(ret == 0, "Release returned %u\n", ret); - sample = create_sample(wma_encoded_data + wma_block_size, wma_block_size - wma_block_size / 2); - hr = IMFTransform_ProcessInput(transform, 0, sample, 0); -- todo_wine - ok(hr == S_OK, "ProcessInput returned %#x\n", hr); - ret = IMFSample_Release(sample); - ok(ret == 0, "Release returned %u\n", ret); - sample = create_sample(wma_encoded_data, wma_block_size); - hr = IMFTransform_ProcessInput(transform, 0, sample, 0); -- todo_wine - ok(hr == S_OK, "ProcessInput returned %#x\n", hr); - hr = IMFTransform_ProcessInput(transform, 0, sample, 0); -- todo_wine - ok(hr == MF_E_NOTACCEPTING, "ProcessInput returned %#x\n", hr); - ret = IMFSample_Release(sample); -- todo_wine - ok(ret == 1, "Release returned %u\n", ret); - - /* As output_info.dwFlags doesn't have MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES -@@ -6248,7 +6243,6 @@ static void test_wma_decoder(void) - - sample = create_sample(wma_encoded_data, wma_block_size); - hr = IMFTransform_ProcessInput(transform, 0, sample, 0); -- todo_wine - ok(hr == MF_E_NOTACCEPTING, "ProcessInput returned %#x\n", hr); - ret = IMFSample_Release(sample); - ok(ret == 0, "Release returned %u\n", ret); -diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h -index 6432ae37fc0..8c7e1795fea 100644 ---- a/dlls/winegstreamer/gst_private.h -+++ b/dlls/winegstreamer/gst_private.h -@@ -103,6 +103,7 @@ bool wg_parser_stream_drain(struct wg_parser_stream *stream); - struct wg_transform *wg_transform_create(const struct wg_encoded_format *input_format, - const struct wg_format *output_format) DECLSPEC_HIDDEN; - void wg_transform_destroy(struct wg_transform *transform) DECLSPEC_HIDDEN; -+HRESULT wg_transform_push_data(struct wg_transform *transform, const void *data, uint32_t size) DECLSPEC_HIDDEN; - - unsigned int wg_format_get_max_size(const struct wg_format *format); - -diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c -index d3e87973fdf..cb21b54f7df 100644 ---- a/dlls/winegstreamer/main.c -+++ b/dlls/winegstreamer/main.c -@@ -307,6 +307,18 @@ void wg_transform_destroy(struct wg_transform *transform) - __wine_unix_call(unix_handle, unix_wg_transform_destroy, transform); - } - -+HRESULT wg_transform_push_data(struct wg_transform *transform, const void *data, uint32_t size) -+{ -+ struct wg_transform_push_data_params params = -+ { -+ .transform = transform, -+ .data = data, -+ .size = size, -+ }; -+ -+ return __wine_unix_call(unix_handle, unix_wg_transform_push_data, ¶ms); -+} -+ - BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved) - { - if (reason == DLL_PROCESS_ATTACH) -diff --git a/dlls/winegstreamer/unix_private.h b/dlls/winegstreamer/unix_private.h -index e6b0f3636f7..baa7f81926c 100644 ---- a/dlls/winegstreamer/unix_private.h -+++ b/dlls/winegstreamer/unix_private.h -@@ -29,5 +29,6 @@ extern GstCaps *wg_format_to_caps(const struct wg_format *format) DECLSPEC_HIDDE - - extern NTSTATUS wg_transform_create(void *args) DECLSPEC_HIDDEN; - extern NTSTATUS wg_transform_destroy(void *args) DECLSPEC_HIDDEN; -+extern NTSTATUS wg_transform_push_data(void *args) DECLSPEC_HIDDEN; - - #endif /* __WINE_WINEGSTREAMER_UNIX_PRIVATE_H */ -diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h -index 51ffc5d3efe..b361fea36d1 100644 ---- a/dlls/winegstreamer/unixlib.h -+++ b/dlls/winegstreamer/unixlib.h -@@ -311,6 +311,13 @@ struct wg_transform_create_params - const struct wg_format *output_format; - }; - -+struct wg_transform_push_data_params -+{ -+ struct wg_transform *transform; -+ const void *data; -+ UINT32 size; -+}; -+ - enum unix_funcs - { - unix_wg_parser_create, -@@ -346,6 +353,8 @@ enum unix_funcs - unix_wg_transform_destroy, - - unix_wg_parser_stream_drain, -+ -+ unix_wg_transform_push_data, - }; - - #endif /* __WINE_WINEGSTREAMER_UNIXLIB_H */ -diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index 02bf639962f..a5dfa0cf7ee 100644 ---- a/dlls/winegstreamer/wg_parser.c -+++ b/dlls/winegstreamer/wg_parser.c -@@ -2668,4 +2668,6 @@ const unixlib_entry_t __wine_unix_call_funcs[] = - X(wg_transform_destroy), - - X(wg_parser_stream_drain), -+ -+ X(wg_transform_push_data), - }; -diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c -index d96923594e2..2137c4c8821 100644 ---- a/dlls/winegstreamer/wg_transform.c -+++ b/dlls/winegstreamer/wg_transform.c -@@ -34,6 +34,7 @@ - - #include "winternl.h" - #include "dshow.h" -+#include "mferror.h" - - #include "unix_private.h" - -@@ -340,3 +341,24 @@ failed: - wg_transform_destroy(transform); - return E_FAIL; - } -+ -+NTSTATUS wg_transform_push_data(void *args) -+{ -+ struct wg_transform_push_data_params *params = args; -+ struct wg_transform *transform = params->transform; -+ GstBuffer *buffer; -+ GstFlowReturn ret; -+ -+ buffer = gst_buffer_new_and_alloc(params->size); -+ gst_buffer_fill(buffer, 0, params->data, params->size); -+ -+ ret = gst_pad_push(transform->my_src, buffer); -+ if (ret) -+ { -+ GST_ERROR("Failed to push buffer %d", ret); -+ return MF_E_NOTACCEPTING; -+ } -+ -+ GST_INFO("Pushed %u bytes", params->size); -+ return S_OK; -+} -diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c -index db6c8a677f6..c9472bde019 100644 ---- a/dlls/winegstreamer/wma_decoder.c -+++ b/dlls/winegstreamer/wma_decoder.c -@@ -54,6 +54,7 @@ struct wma_decoder - IMFMediaType *input_type; - IMFMediaType *output_type; - -+ IMFSample *input_sample; - struct wg_transform *wg_transform; - }; - -@@ -131,6 +132,8 @@ static ULONG WINAPI unknown_Release(IUnknown *iface) - - if (!refcount) - { -+ if (decoder->input_sample) -+ IMFSample_Release(decoder->input_sample); - if (decoder->wg_transform) - wg_transform_destroy(decoder->wg_transform); - if (decoder->input_type) -@@ -523,8 +526,44 @@ static HRESULT WINAPI transform_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_ - - static HRESULT WINAPI transform_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags) - { -- FIXME("iface %p, id %lu, sample %p, flags %#lx stub!\n", iface, id, sample, flags); -- return E_NOTIMPL; -+ struct wma_decoder *decoder = impl_from_IMFTransform(iface); -+ IMFMediaBuffer *media_buffer; -+ MFT_INPUT_STREAM_INFO info; -+ DWORD buffer_size; -+ BYTE *buffer; -+ HRESULT hr; -+ -+ TRACE("iface %p, id %lu, sample %p, flags %#lx.\n", iface, id, sample, flags); -+ -+ if (FAILED(hr = IMFTransform_GetInputStreamInfo(iface, 0, &info))) -+ return hr; -+ -+ if (!decoder->wg_transform) -+ return MF_E_TRANSFORM_TYPE_NOT_SET; -+ -+ if (decoder->input_sample) -+ return MF_E_NOTACCEPTING; -+ -+ if (FAILED(hr = IMFSample_ConvertToContiguousBuffer(sample, &media_buffer))) -+ return hr; -+ -+ if (FAILED(hr = IMFMediaBuffer_GetCurrentLength(media_buffer, &buffer_size))) -+ return hr; -+ -+ if (!(buffer_size = (buffer_size / info.cbSize) * info.cbSize)) -+ return S_OK; -+ -+ if (FAILED(hr = IMFMediaBuffer_Lock(media_buffer, &buffer, NULL, NULL))) -+ goto done; -+ -+ if (SUCCEEDED(hr = wg_transform_push_data(decoder->wg_transform, buffer, buffer_size))) -+ IMFSample_AddRef((decoder->input_sample = sample)); -+ -+ IMFMediaBuffer_Unlock(media_buffer); -+ -+done: -+ IMFMediaBuffer_Release(media_buffer); -+ return hr; - } - - static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count, --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0064-winegstreamer-Implement-WMA-decoder-ProcessOutput.patch b/patches/mfplat-streaming-support/0064-winegstreamer-Implement-WMA-decoder-ProcessOutput.patch deleted file mode 100644 index 45b51603..00000000 --- a/patches/mfplat-streaming-support/0064-winegstreamer-Implement-WMA-decoder-ProcessOutput.patch +++ /dev/null @@ -1,407 +0,0 @@ -From 4c1eae2084677337da00722ed93e9b3032c8a6db Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Fri, 21 Jan 2022 14:31:44 +0100 -Subject: [PATCH 64/88] winegstreamer: Implement WMA decoder ProcessOutput. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51931 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52391 -CW-Bug-Id: #19854 ---- - dlls/mf/tests/mf.c | 19 ++------ - dlls/winegstreamer/gst_private.h | 1 + - dlls/winegstreamer/main.c | 11 +++++ - dlls/winegstreamer/unix_private.h | 1 + - dlls/winegstreamer/unixlib.h | 19 ++++++++ - dlls/winegstreamer/wg_parser.c | 1 + - dlls/winegstreamer/wg_transform.c | 76 ++++++++++++++++++++++++++++++- - dlls/winegstreamer/wma_decoder.c | 59 +++++++++++++++++++++++- - 8 files changed, 169 insertions(+), 18 deletions(-) - -diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c -index d78f0051714..4a81191bcf6 100644 ---- a/dlls/mf/tests/mf.c -+++ b/dlls/mf/tests/mf.c -@@ -6229,16 +6229,13 @@ static void test_wma_decoder(void) - status = 0xdeadbeef; - memset(&output, 0, sizeof(output)); - hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status); -- todo_wine - ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#x\n", hr); - ok(output.dwStreamID == 0, "got dwStreamID %u\n", output.dwStreamID); - ok(!output.pSample, "got pSample %p\n", output.pSample); -- todo_wine - ok(output.dwStatus == MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE || - broken(output.dwStatus == (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE|MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE)) /* Win7 */, - "got dwStatus %#x\n", output.dwStatus); - ok(!output.pEvents, "got pEvents %p\n", output.pEvents); -- todo_wine - ok(status == 0, "got status %#x\n", status); - - sample = create_sample(wma_encoded_data, wma_block_size); -@@ -6250,14 +6247,11 @@ static void test_wma_decoder(void) - status = 0xdeadbeef; - memset(&output, 0, sizeof(output)); - hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status); -- todo_wine - ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#x\n", hr); - ok(!output.pSample, "got pSample %p\n", output.pSample); -- todo_wine - ok(output.dwStatus == MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE || - broken(output.dwStatus == (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE|MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE)) /* Win7 */, - "got dwStatus %#x\n", output.dwStatus); -- todo_wine - ok(status == 0, "got status %#x\n", status); - - i = 1; -@@ -6291,7 +6285,6 @@ static void test_wma_decoder(void) - hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status); - } - -- todo_wine - ok(hr == S_OK, "ProcessOutput returned %#x\n", hr); - ok(output.pSample == sample, "got pSample %p\n", output.pSample); - -@@ -6304,7 +6297,8 @@ static void test_wma_decoder(void) - "got dwStatus %#x\n", output.dwStatus); - ok(status == 0, "got status %#x\n", status); - if (output.dwStatus == MFT_OUTPUT_DATA_BUFFER_INCOMPLETE || -- broken(output.dwStatus == (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE|7))) -+ broken(output.dwStatus == (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE|7)) || -+ !strcmp(winetest_platform, "wine")) - { - check_sample(sample, wma_decoded_data, sizeof(wma_decoded_data), NULL); - i += sizeof(wma_decoded_data); -@@ -6323,14 +6317,12 @@ static void test_wma_decoder(void) - output.pSample = sample; - hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status); - } -- todo_wine -- ok(i == 0xe000, "ProcessOutput produced %#x bytes\n", i); -+ if (!strcmp(winetest_platform, "wine")) ok(i == 0x10000, "ProcessOutput produced %#x bytes\n", i); -+ else ok(i == 0xe000, "ProcessOutput produced %#x bytes\n", i); - -- todo_wine - ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#x\n", hr); - ok(output.pSample == sample, "got pSample %p\n", output.pSample); - ok(output.dwStatus == 0, "got dwStatus %#x\n", output.dwStatus); -- todo_wine - ok(status == 0, "got status %#x\n", status); - ret = IMFSample_Release(sample); - ok(ret == 0, "Release returned %u\n", ret); -@@ -6340,13 +6332,11 @@ static void test_wma_decoder(void) - memset(&output, 0, sizeof(output)); - output.pSample = sample; - hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status); -- todo_wine - ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#x\n", hr); - ok(output.pSample == sample, "got pSample %p\n", output.pSample); - ok(output.dwStatus == 0 || - broken(output.dwStatus == (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE|7)) /* Win7 */, - "got dwStatus %#x\n", output.dwStatus); -- todo_wine - ok(status == 0, "got status %#x\n", status); - check_sample(sample, NULL, 0, NULL); - ret = IMFSample_Release(sample); -@@ -6354,7 +6344,6 @@ static void test_wma_decoder(void) - - sample = create_sample(wma_encoded_data, wma_block_size); - hr = IMFTransform_ProcessInput(transform, 0, sample, 0); -- todo_wine - ok(hr == S_OK, "ProcessInput returned %#x\n", hr); - - ret = IMFTransform_Release(transform); -diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h -index 8c7e1795fea..af30e944865 100644 ---- a/dlls/winegstreamer/gst_private.h -+++ b/dlls/winegstreamer/gst_private.h -@@ -104,6 +104,7 @@ struct wg_transform *wg_transform_create(const struct wg_encoded_format *input_f - const struct wg_format *output_format) DECLSPEC_HIDDEN; - void wg_transform_destroy(struct wg_transform *transform) DECLSPEC_HIDDEN; - HRESULT wg_transform_push_data(struct wg_transform *transform, const void *data, uint32_t size) DECLSPEC_HIDDEN; -+HRESULT wg_transform_read_data(struct wg_transform *transform, struct wg_sample *sample) DECLSPEC_HIDDEN; - - unsigned int wg_format_get_max_size(const struct wg_format *format); - -diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c -index cb21b54f7df..fd73bfc289a 100644 ---- a/dlls/winegstreamer/main.c -+++ b/dlls/winegstreamer/main.c -@@ -319,6 +319,17 @@ HRESULT wg_transform_push_data(struct wg_transform *transform, const void *data, - return __wine_unix_call(unix_handle, unix_wg_transform_push_data, ¶ms); - } - -+HRESULT wg_transform_read_data(struct wg_transform *transform, struct wg_sample *sample) -+{ -+ struct wg_transform_read_data_params params = -+ { -+ .transform = transform, -+ .sample = sample, -+ }; -+ -+ return __wine_unix_call(unix_handle, unix_wg_transform_read_data, ¶ms); -+} -+ - BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved) - { - if (reason == DLL_PROCESS_ATTACH) -diff --git a/dlls/winegstreamer/unix_private.h b/dlls/winegstreamer/unix_private.h -index baa7f81926c..1b055436ba5 100644 ---- a/dlls/winegstreamer/unix_private.h -+++ b/dlls/winegstreamer/unix_private.h -@@ -30,5 +30,6 @@ extern GstCaps *wg_format_to_caps(const struct wg_format *format) DECLSPEC_HIDDE - extern NTSTATUS wg_transform_create(void *args) DECLSPEC_HIDDEN; - extern NTSTATUS wg_transform_destroy(void *args) DECLSPEC_HIDDEN; - extern NTSTATUS wg_transform_push_data(void *args) DECLSPEC_HIDDEN; -+extern NTSTATUS wg_transform_read_data(void *args) DECLSPEC_HIDDEN; - - #endif /* __WINE_WINEGSTREAMER_UNIX_PRIVATE_H */ -diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h -index b361fea36d1..0df245408ee 100644 ---- a/dlls/winegstreamer/unixlib.h -+++ b/dlls/winegstreamer/unixlib.h -@@ -318,6 +318,24 @@ struct wg_transform_push_data_params - UINT32 size; - }; - -+enum wg_sample_flags -+{ -+ WG_SAMPLE_FLAG_INCOMPLETE = 1, -+}; -+ -+struct wg_sample -+{ -+ UINT32 flags; -+ BYTE *data; -+ UINT32 size; -+}; -+ -+struct wg_transform_read_data_params -+{ -+ struct wg_transform *transform; -+ struct wg_sample *sample; -+}; -+ - enum unix_funcs - { - unix_wg_parser_create, -@@ -355,6 +373,7 @@ enum unix_funcs - unix_wg_parser_stream_drain, - - unix_wg_transform_push_data, -+ unix_wg_transform_read_data, - }; - - #endif /* __WINE_WINEGSTREAMER_UNIXLIB_H */ -diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index a5dfa0cf7ee..3217c78e864 100644 ---- a/dlls/winegstreamer/wg_parser.c -+++ b/dlls/winegstreamer/wg_parser.c -@@ -2670,4 +2670,5 @@ const unixlib_entry_t __wine_unix_call_funcs[] = - X(wg_parser_stream_drain), - - X(wg_transform_push_data), -+ X(wg_transform_read_data), - }; -diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c -index 2137c4c8821..1f8b35920b4 100644 ---- a/dlls/winegstreamer/wg_transform.c -+++ b/dlls/winegstreamer/wg_transform.c -@@ -38,14 +38,24 @@ - - #include "unix_private.h" - -+#include "wine/list.h" -+ - GST_DEBUG_CATEGORY_EXTERN(wine); - #define GST_CAT_DEFAULT wine - -+struct wg_transform_sample -+{ -+ struct list entry; -+ GstSample *sample; -+}; -+ - struct wg_transform - { - GstElement *container; - GstPad *my_src, *my_sink; - GstPad *their_sink, *their_src; -+ pthread_mutex_t mutex; -+ struct list samples; - }; - - static GstCaps *wg_format_to_caps_xwma(const struct wg_encoded_format *format) -@@ -99,17 +109,29 @@ static GstCaps *wg_encoded_format_to_caps(const struct wg_encoded_format *format - static GstFlowReturn transform_sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *buffer) - { - struct wg_transform *transform = gst_pad_get_element_private(pad); -+ struct wg_transform_sample *sample; - - GST_INFO("transform %p, buffer %p.", transform, buffer); - -- gst_buffer_unref(buffer); -+ if (!(sample = malloc(sizeof(*sample)))) -+ GST_ERROR("Failed to allocate transform sample entry"); -+ else -+ { -+ pthread_mutex_lock(&transform->mutex); -+ if (!(sample->sample = gst_sample_new(buffer, NULL, NULL, NULL))) -+ GST_ERROR("Failed to allocate transform sample"); -+ list_add_tail(&transform->samples, &sample->entry); -+ pthread_mutex_unlock(&transform->mutex); -+ } - -+ gst_buffer_unref(buffer); - return GST_FLOW_OK; - } - - NTSTATUS wg_transform_destroy(void *args) - { - struct wg_transform *transform = args; -+ struct wg_transform_sample *sample, *next; - - if (transform->container) - gst_element_set_state(transform->container, GST_STATE_NULL); -@@ -132,6 +154,13 @@ NTSTATUS wg_transform_destroy(void *args) - if (transform->my_src) - g_object_unref(transform->my_src); - -+ LIST_FOR_EACH_ENTRY_SAFE(sample, next, &transform->samples, struct wg_transform_sample, entry) -+ { -+ gst_sample_unref(sample->sample); -+ list_remove(&sample->entry); -+ free(sample); -+ } -+ - free(transform); - return S_OK; - } -@@ -224,6 +253,8 @@ NTSTATUS wg_transform_create(void *args) - if (!(transform = calloc(1, sizeof(*transform)))) - return E_OUTOFMEMORY; - -+ list_init(&transform->samples); -+ - src_caps = wg_encoded_format_to_caps(&input_format); - assert(src_caps); - sink_caps = wg_format_to_caps(&output_format); -@@ -362,3 +393,46 @@ NTSTATUS wg_transform_push_data(void *args) - GST_INFO("Pushed %u bytes", params->size); - return S_OK; - } -+ -+NTSTATUS wg_transform_read_data(void *args) -+{ -+ struct wg_transform_read_data_params *params = args; -+ struct wg_transform *transform = params->transform; -+ struct wg_sample *read_sample = params->sample; -+ struct wg_transform_sample *transform_sample; -+ GstBuffer *buffer; -+ struct list *head; -+ GstMapInfo info; -+ -+ pthread_mutex_lock(&transform->mutex); -+ if (!(head = list_head(&transform->samples))) -+ { -+ pthread_mutex_unlock(&transform->mutex); -+ return MF_E_TRANSFORM_NEED_MORE_INPUT; -+ } -+ -+ transform_sample = LIST_ENTRY(head, struct wg_transform_sample, entry); -+ buffer = gst_sample_get_buffer(transform_sample->sample); -+ -+ gst_buffer_map(buffer, &info, GST_MAP_READ); -+ if (read_sample->size > info.size) -+ read_sample->size = info.size; -+ memcpy(read_sample->data, info.data, read_sample->size); -+ gst_buffer_unmap(buffer, &info); -+ -+ if (info.size > read_sample->size) -+ { -+ read_sample->flags |= WG_SAMPLE_FLAG_INCOMPLETE; -+ gst_buffer_resize(buffer, read_sample->size, -1); -+ } -+ else -+ { -+ gst_sample_unref(transform_sample->sample); -+ list_remove(&transform_sample->entry); -+ free(transform_sample); -+ } -+ pthread_mutex_unlock(&transform->mutex); -+ -+ GST_INFO("Read %u bytes, flags %#x", read_sample->size, read_sample->flags); -+ return S_OK; -+} -diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c -index c9472bde019..cac345be269 100644 ---- a/dlls/winegstreamer/wma_decoder.c -+++ b/dlls/winegstreamer/wma_decoder.c -@@ -569,8 +569,63 @@ done: - static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count, - MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status) - { -- FIXME("iface %p, flags %#lx, count %lu, samples %p, status %p stub!\n", iface, flags, count, samples, status); -- return E_NOTIMPL; -+ struct wma_decoder *decoder = impl_from_IMFTransform(iface); -+ struct wg_sample wg_sample = {0}; -+ IMFMediaBuffer *media_buffer; -+ MFT_OUTPUT_STREAM_INFO info; -+ DWORD buffer_size; -+ HRESULT hr; -+ -+ TRACE("iface %p, flags %#lx, count %lu, samples %p, status %p.\n", iface, flags, count, samples, status); -+ -+ if (count > 1) -+ { -+ FIXME("Not implemented count %lu\n", count); -+ return E_NOTIMPL; -+ } -+ -+ if (FAILED(hr = IMFTransform_GetOutputStreamInfo(iface, 0, &info))) -+ return hr; -+ -+ if (!decoder->wg_transform) -+ return MF_E_TRANSFORM_TYPE_NOT_SET; -+ -+ *status = 0; -+ samples[0].dwStatus = 0; -+ if (!samples[0].pSample) -+ { -+ samples[0].dwStatus = MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE; -+ return MF_E_TRANSFORM_NEED_MORE_INPUT; -+ } -+ -+ if (FAILED(hr = IMFSample_ConvertToContiguousBuffer(samples[0].pSample, &media_buffer))) -+ return hr; -+ -+ if (FAILED(hr = IMFMediaBuffer_Lock(media_buffer, &wg_sample.data, &buffer_size, NULL))) -+ goto done; -+ wg_sample.size = buffer_size; -+ -+ if (wg_sample.size < info.cbSize) -+ hr = MF_E_BUFFERTOOSMALL; -+ else if (SUCCEEDED(hr = wg_transform_read_data(decoder->wg_transform, &wg_sample))) -+ { -+ if (wg_sample.flags & WG_SAMPLE_FLAG_INCOMPLETE) -+ samples[0].dwStatus |= MFT_OUTPUT_DATA_BUFFER_INCOMPLETE; -+ } -+ else -+ { -+ if (decoder->input_sample) -+ IMFSample_Release(decoder->input_sample); -+ decoder->input_sample = NULL; -+ wg_sample.size = 0; -+ } -+ -+ IMFMediaBuffer_Unlock(media_buffer); -+ -+done: -+ IMFMediaBuffer_SetCurrentLength(media_buffer, wg_sample.size); -+ IMFMediaBuffer_Release(media_buffer); -+ return hr; - } - - static const IMFTransformVtbl transform_vtbl = --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0066-winegstreamer-Introduce-new-H264-decoder-transform-s.patch b/patches/mfplat-streaming-support/0066-winegstreamer-Introduce-new-H264-decoder-transform-s.patch deleted file mode 100644 index a035d728..00000000 --- a/patches/mfplat-streaming-support/0066-winegstreamer-Introduce-new-H264-decoder-transform-s.patch +++ /dev/null @@ -1,363 +0,0 @@ -From e0fce42d02ca3c2975384f04729d7b67021fc8b0 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Tue, 18 Jan 2022 13:09:07 +0100 -Subject: [PATCH 66/88] winegstreamer: Introduce new H264 decoder transform - stub. - -As a remplacement for the previously added transform. - -For: Call of Duty III, Mortal Kombat 11, Shadow Warrior 2, -Yakuza 4 Remastered, Hard Reset Redux. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183 -CW-Bug-Id: #16839 -CW-Bug-Id: #18678 -CW-Bug-Id: #19362 ---- - dlls/winegstreamer/Makefile.in | 1 + - dlls/winegstreamer/gst_private.h | 1 + - dlls/winegstreamer/h264_decoder.c | 279 ++++++++++++++++++++++++++++++ - dlls/winegstreamer/mfplat.c | 7 +- - 4 files changed, 282 insertions(+), 6 deletions(-) - create mode 100644 dlls/winegstreamer/h264_decoder.c - -diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in -index 294d3b199a5..c4f0f1cad2c 100644 ---- a/dlls/winegstreamer/Makefile.in -+++ b/dlls/winegstreamer/Makefile.in -@@ -10,6 +10,7 @@ C_SRCS = \ - audioconvert.c \ - colorconvert.c \ - decode_transform.c \ -+ h264_decoder.c \ - main.c \ - media_source.c \ - mfplat.c \ -diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h -index af30e944865..fa73fecb10d 100644 ---- a/dlls/winegstreamer/gst_private.h -+++ b/dlls/winegstreamer/gst_private.h -@@ -128,6 +128,7 @@ void mf_media_type_to_wg_encoded_format(IMFMediaType *type, struct wg_encoded_fo - - HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj); - -+HRESULT h264_decoder_create(REFIID riid, void **ret); - HRESULT audio_converter_create(REFIID riid, void **ret); - HRESULT color_converter_create(REFIID riid, void **ret); - -diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c -new file mode 100644 -index 00000000000..5db72c55151 ---- /dev/null -+++ b/dlls/winegstreamer/h264_decoder.c -@@ -0,0 +1,279 @@ -+/* H264 Decoder Transform -+ * -+ * Copyright 2022 RĂ©mi Bernon for CodeWeavers -+ * -+ * This library is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU Lesser General Public -+ * License as published by the Free Software Foundation; either -+ * version 2.1 of the License, or (at your option) any later version. -+ * -+ * This library is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -+ * Lesser General Public License for more details. -+ * -+ * You should have received a copy of the GNU Lesser General Public -+ * License along with this library; if not, write to the Free Software -+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA -+ */ -+ -+#include "gst_private.h" -+ -+#include "mfapi.h" -+#include "mferror.h" -+#include "mfobjects.h" -+#include "mftransform.h" -+#include "wmcodecdsp.h" -+ -+#include "wine/debug.h" -+#include "wine/heap.h" -+ -+WINE_DEFAULT_DEBUG_CHANNEL(mfplat); -+ -+struct h264_decoder -+{ -+ IMFTransform IMFTransform_iface; -+ LONG refcount; -+}; -+ -+static struct h264_decoder *impl_from_IMFTransform(IMFTransform *iface) -+{ -+ return CONTAINING_RECORD(iface, struct h264_decoder, IMFTransform_iface); -+} -+ -+static HRESULT WINAPI h264_decoder_QueryInterface(IMFTransform *iface, REFIID iid, void **out) -+{ -+ struct h264_decoder *decoder = impl_from_IMFTransform(iface); -+ -+ TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out); -+ -+ if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IMFTransform)) -+ *out = &decoder->IMFTransform_iface; -+ else -+ { -+ *out = NULL; -+ WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); -+ return E_NOINTERFACE; -+ } -+ -+ IUnknown_AddRef((IUnknown *)*out); -+ return S_OK; -+} -+ -+static ULONG WINAPI h264_decoder_AddRef(IMFTransform *iface) -+{ -+ struct h264_decoder *decoder = impl_from_IMFTransform(iface); -+ ULONG refcount = InterlockedIncrement(&decoder->refcount); -+ -+ TRACE("iface %p increasing refcount to %lu.\n", decoder, refcount); -+ -+ return refcount; -+} -+ -+static ULONG WINAPI h264_decoder_Release(IMFTransform *iface) -+{ -+ struct h264_decoder *decoder = impl_from_IMFTransform(iface); -+ ULONG refcount = InterlockedDecrement(&decoder->refcount); -+ -+ TRACE("iface %p decreasing refcount to %lu.\n", decoder, refcount); -+ -+ if (!refcount) -+ free(decoder); -+ -+ return refcount; -+} -+ -+static HRESULT WINAPI h264_decoder_GetStreamLimits(IMFTransform *iface, DWORD *input_minimum, DWORD *input_maximum, -+ DWORD *output_minimum, DWORD *output_maximum) -+{ -+ FIXME("iface %p, input_minimum %p, input_maximum %p, output_minimum %p, output_maximum %p stub!\n", -+ iface, input_minimum, input_maximum, output_minimum, output_maximum); -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI h264_decoder_GetStreamCount(IMFTransform *iface, DWORD *inputs, DWORD *outputs) -+{ -+ FIXME("iface %p, inputs %p, outputs %p stub!\n", iface, inputs, outputs); -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI h264_decoder_GetStreamIDs(IMFTransform *iface, DWORD input_size, DWORD *inputs, -+ DWORD output_size, DWORD *outputs) -+{ -+ FIXME("iface %p, input_size %lu, inputs %p, output_size %lu, outputs %p stub!\n", -+ iface, input_size, inputs, output_size, outputs); -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI h264_decoder_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info) -+{ -+ FIXME("iface %p, id %#lx, info %p stub!\n", iface, id, info); -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI h264_decoder_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info) -+{ -+ FIXME("iface %p, id %#lx, info %p stub!\n", iface, id, info); -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI h264_decoder_GetAttributes(IMFTransform *iface, IMFAttributes **attributes) -+{ -+ FIXME("iface %p, attributes %p stub!\n", iface, attributes); -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI h264_decoder_GetInputStreamAttributes(IMFTransform *iface, DWORD id, -+ IMFAttributes **attributes) -+{ -+ FIXME("iface %p, id %#lx, attributes %p stub!\n", iface, id, attributes); -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI h264_decoder_GetOutputStreamAttributes(IMFTransform *iface, DWORD id, -+ IMFAttributes **attributes) -+{ -+ FIXME("iface %p, id %#lx, attributes %p stub!\n", iface, id, attributes); -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI h264_decoder_DeleteInputStream(IMFTransform *iface, DWORD id) -+{ -+ FIXME("iface %p, id %#lx stub!\n", iface, id); -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI h264_decoder_AddInputStreams(IMFTransform *iface, DWORD streams, DWORD *ids) -+{ -+ FIXME("iface %p, streams %lu, ids %p stub!\n", iface, streams, ids); -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI h264_decoder_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index, -+ IMFMediaType **type) -+{ -+ FIXME("iface %p, id %#lx, index %#lx, type %p stub!\n", iface, id, index, type); -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI h264_decoder_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index, -+ IMFMediaType **type) -+{ -+ FIXME("iface %p, id %#lx, index %#lx, type %p stub!\n", iface, id, index, type); -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI h264_decoder_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) -+{ -+ FIXME("iface %p, id %#lx, type %p, flags %#lx stub!\n", iface, id, type, flags); -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI h264_decoder_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) -+{ -+ FIXME("iface %p, id %#lx, type %p, flags %#lx stub!\n", iface, id, type, flags); -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI h264_decoder_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) -+{ -+ FIXME("iface %p, id %#lx, type %p stub!\n", iface, id, type); -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI h264_decoder_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) -+{ -+ FIXME("iface %p, id %#lx, type %p stub!\n", iface, id, type); -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI h264_decoder_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags) -+{ -+ FIXME("iface %p, id %#lx, flags %p stub!\n", iface, id, flags); -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI h264_decoder_GetOutputStatus(IMFTransform *iface, DWORD *flags) -+{ -+ FIXME("iface %p, flags %p stub!\n", iface, flags); -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI h264_decoder_SetOutputBounds(IMFTransform *iface, LONGLONG lower, LONGLONG upper) -+{ -+ FIXME("iface %p, lower %s, upper %s stub!\n", iface, -+ wine_dbgstr_longlong(lower), wine_dbgstr_longlong(upper)); -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI h264_decoder_ProcessEvent(IMFTransform *iface, DWORD id, IMFMediaEvent *event) -+{ -+ FIXME("iface %p, id %#lx, event %p stub!\n", iface, id, event); -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI h264_decoder_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param) -+{ -+ FIXME("iface %p, message %#x, param %p stub!\n", iface, message, (void *)param); -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI h264_decoder_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags) -+{ -+ FIXME("iface %p, id %#lx, sample %p, flags %#lx stub!\n", iface, id, sample, flags); -+ return E_NOTIMPL; -+} -+ -+static HRESULT WINAPI h264_decoder_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count, -+ MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status) -+{ -+ FIXME("iface %p, flags %#lx, count %lu, samples %p, status %p stub!\n", iface, flags, count, samples, status); -+ return E_NOTIMPL; -+} -+ -+static const IMFTransformVtbl h264_decoder_vtbl = -+{ -+ h264_decoder_QueryInterface, -+ h264_decoder_AddRef, -+ h264_decoder_Release, -+ h264_decoder_GetStreamLimits, -+ h264_decoder_GetStreamCount, -+ h264_decoder_GetStreamIDs, -+ h264_decoder_GetInputStreamInfo, -+ h264_decoder_GetOutputStreamInfo, -+ h264_decoder_GetAttributes, -+ h264_decoder_GetInputStreamAttributes, -+ h264_decoder_GetOutputStreamAttributes, -+ h264_decoder_DeleteInputStream, -+ h264_decoder_AddInputStreams, -+ h264_decoder_GetInputAvailableType, -+ h264_decoder_GetOutputAvailableType, -+ h264_decoder_SetInputType, -+ h264_decoder_SetOutputType, -+ h264_decoder_GetInputCurrentType, -+ h264_decoder_GetOutputCurrentType, -+ h264_decoder_GetInputStatus, -+ h264_decoder_GetOutputStatus, -+ h264_decoder_SetOutputBounds, -+ h264_decoder_ProcessEvent, -+ h264_decoder_ProcessMessage, -+ h264_decoder_ProcessInput, -+ h264_decoder_ProcessOutput, -+}; -+ -+HRESULT h264_decoder_create(REFIID riid, void **ret) -+{ -+ struct h264_decoder *decoder; -+ -+ TRACE("riid %s, ret %p.\n", debugstr_guid(riid), ret); -+ -+ if (!(decoder = calloc(1, sizeof(*decoder)))) -+ return E_OUTOFMEMORY; -+ -+ decoder->IMFTransform_iface.lpVtbl = &h264_decoder_vtbl; -+ decoder->refcount = 1; -+ -+ *ret = &decoder->IMFTransform_iface; -+ TRACE("Created decoder %p\n", *ret); -+ return S_OK; -+} -diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index 5633331359d..ca26c767125 100644 ---- a/dlls/winegstreamer/mfplat.c -+++ b/dlls/winegstreamer/mfplat.c -@@ -400,11 +400,6 @@ static const GUID CLSID_GStreamerByteStreamHandler = {0x317df618, 0x5e5a, 0x468a - - static const GUID CLSID_WINEAudioConverter = {0x6a170414,0xaad9,0x4693,{0xb8,0x06,0x3a,0x0c,0x47,0xc5,0x70,0xd6}}; - --static HRESULT h264_decoder_create(REFIID riid, void **ret) --{ -- return decode_transform_create(riid, ret, DECODER_TYPE_H264); --} -- - static const struct class_object - { - const GUID *clsid; -@@ -549,7 +544,7 @@ mfts[] = - color_converter_supported_types, - }, - { -- &CLSID_MSAACDecMFT, -+ &CLSID_MSH264DecoderMFT, - &MFT_CATEGORY_VIDEO_DECODER, - h264_decoderW, - MFT_ENUM_FLAG_SYNCMFT, --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0068-winegstreamer-Return-S_OK-from-H264-decoder-ProcessM.patch b/patches/mfplat-streaming-support/0068-winegstreamer-Return-S_OK-from-H264-decoder-ProcessM.patch deleted file mode 100644 index 22e274e8..00000000 --- a/patches/mfplat-streaming-support/0068-winegstreamer-Return-S_OK-from-H264-decoder-ProcessM.patch +++ /dev/null @@ -1,36 +0,0 @@ -From ac5e4d49d48fb8b4f1070103c856f0b7363a7d03 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Tue, 18 Jan 2022 13:33:36 +0100 -Subject: [PATCH 68/88] winegstreamer: Return S_OK from H264 decoder - ProcessMessage. - -For: Call of Duty III, Mortal Kombat 11, Shadow Warrior 2, -Yakuza 4 Remastered, Hard Reset Redux. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183 -CW-Bug-Id: #16839 -CW-Bug-Id: #18678 -CW-Bug-Id: #19362 ---- - dlls/winegstreamer/h264_decoder.c | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c -index f46d6d77f8e..55f40ad7660 100644 ---- a/dlls/winegstreamer/h264_decoder.c -+++ b/dlls/winegstreamer/h264_decoder.c -@@ -216,7 +216,7 @@ static HRESULT WINAPI h264_decoder_ProcessEvent(IMFTransform *iface, DWORD id, I - static HRESULT WINAPI h264_decoder_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param) - { - FIXME("iface %p, message %#x, param %p stub!\n", iface, message, (void *)param); -- return E_NOTIMPL; -+ return S_OK; - } - - static HRESULT WINAPI h264_decoder_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags) --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0069-winegstreamer-Implement-H264-decoder-SetInputType.patch b/patches/mfplat-streaming-support/0069-winegstreamer-Implement-H264-decoder-SetInputType.patch deleted file mode 100644 index 6aab242b..00000000 --- a/patches/mfplat-streaming-support/0069-winegstreamer-Implement-H264-decoder-SetInputType.patch +++ /dev/null @@ -1,89 +0,0 @@ -From 34491aae12bd533db2ceb8fdbfcbc0a1ccc54004 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Thu, 10 Feb 2022 09:54:51 +0100 -Subject: [PATCH 69/88] winegstreamer: Implement H264 decoder SetInputType. - -For: Call of Duty III, Mortal Kombat 11, Shadow Warrior 2, -Yakuza 4 Remastered, Hard Reset Redux. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183 -CW-Bug-Id: #16839 -CW-Bug-Id: #18678 -CW-Bug-Id: #19362 ---- - dlls/winegstreamer/h264_decoder.c | 37 +++++++++++++++++++++++++++++-- - 1 file changed, 35 insertions(+), 2 deletions(-) - -diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c -index 55f40ad7660..e0634bedcaa 100644 ---- a/dlls/winegstreamer/h264_decoder.c -+++ b/dlls/winegstreamer/h264_decoder.c -@@ -30,10 +30,16 @@ - - WINE_DEFAULT_DEBUG_CHANNEL(mfplat); - -+static const GUID *h264_decoder_input_types[] = -+{ -+ &MFVideoFormat_H264, -+}; -+ - struct h264_decoder - { - IMFTransform IMFTransform_iface; - LONG refcount; -+ IMFMediaType *input_type; - }; - - static struct h264_decoder *impl_from_IMFTransform(IMFTransform *iface) -@@ -78,7 +84,11 @@ static ULONG WINAPI h264_decoder_Release(IMFTransform *iface) - TRACE("iface %p decreasing refcount to %lu.\n", decoder, refcount); - - if (!refcount) -+ { -+ if (decoder->input_type) -+ IMFMediaType_Release(decoder->input_type); - free(decoder); -+ } - - return refcount; - } -@@ -166,8 +176,31 @@ static HRESULT WINAPI h264_decoder_GetOutputAvailableType(IMFTransform *iface, D - - static HRESULT WINAPI h264_decoder_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) - { -- FIXME("iface %p, id %#lx, type %p, flags %#lx stub!\n", iface, id, type, flags); -- return E_NOTIMPL; -+ struct h264_decoder *decoder = impl_from_IMFTransform(iface); -+ GUID major, subtype; -+ HRESULT hr; -+ ULONG i; -+ -+ TRACE("iface %p, id %#lx, type %p, flags %#lx.\n", iface, id, type, flags); -+ -+ if (FAILED(hr = IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major)) || -+ FAILED(hr = IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype))) -+ return E_INVALIDARG; -+ -+ if (!IsEqualGUID(&major, &MFMediaType_Video)) -+ return MF_E_INVALIDMEDIATYPE; -+ -+ for (i = 0; i < ARRAY_SIZE(h264_decoder_input_types); ++i) -+ if (IsEqualGUID(&subtype, h264_decoder_input_types[i])) -+ break; -+ if (i == ARRAY_SIZE(h264_decoder_input_types)) -+ return MF_E_INVALIDMEDIATYPE; -+ -+ if (decoder->input_type) -+ IMFMediaType_Release(decoder->input_type); -+ IMFMediaType_AddRef((decoder->input_type = type)); -+ -+ return S_OK; - } - - static HRESULT WINAPI h264_decoder_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0070-winegstreamer-Implement-H264-decoder-GetOutputAvaila.patch b/patches/mfplat-streaming-support/0070-winegstreamer-Implement-H264-decoder-GetOutputAvaila.patch deleted file mode 100644 index cdaf860b..00000000 --- a/patches/mfplat-streaming-support/0070-winegstreamer-Implement-H264-decoder-GetOutputAvaila.patch +++ /dev/null @@ -1,196 +0,0 @@ -From 71e9a26475d40d5107b803cbc1c69dbff4a18b93 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Thu, 10 Feb 2022 09:55:30 +0100 -Subject: [PATCH 70/88] winegstreamer: Implement H264 decoder - GetOutputAvailableType. - -For: Call of Duty III, Mortal Kombat 11, Shadow Warrior 2, -Yakuza 4 Remastered, Hard Reset Redux. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183 -CW-Bug-Id: #16839 -CW-Bug-Id: #18678 -CW-Bug-Id: #19362 ---- - dlls/winegstreamer/h264_decoder.c | 141 +++++++++++++++++++++++++++++- - 1 file changed, 138 insertions(+), 3 deletions(-) - -diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c -index e0634bedcaa..78bf317c36f 100644 ---- a/dlls/winegstreamer/h264_decoder.c -+++ b/dlls/winegstreamer/h264_decoder.c -@@ -34,6 +34,14 @@ static const GUID *h264_decoder_input_types[] = - { - &MFVideoFormat_H264, - }; -+static const GUID *h264_decoder_output_types[] = -+{ -+ &MFVideoFormat_NV12, -+ &MFVideoFormat_YV12, -+ &MFVideoFormat_IYUV, -+ &MFVideoFormat_I420, -+ &MFVideoFormat_YUY2, -+}; - - struct h264_decoder - { -@@ -47,6 +55,103 @@ static struct h264_decoder *impl_from_IMFTransform(IMFTransform *iface) - return CONTAINING_RECORD(iface, struct h264_decoder, IMFTransform_iface); - } - -+static HRESULT fill_output_media_type(IMFMediaType *media_type, IMFMediaType *default_type) -+{ -+ UINT32 value, width, height; -+ UINT64 value64; -+ GUID subtype; -+ HRESULT hr; -+ -+ if (FAILED(hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &subtype))) -+ return hr; -+ -+ if (FAILED(hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &value64))) -+ { -+ if (!default_type || FAILED(hr = IMFMediaType_GetUINT64(default_type, &MF_MT_FRAME_SIZE, &value64))) -+ value64 = (UINT64)1920 << 32 | 1080; -+ if (FAILED(hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, value64))) -+ return hr; -+ } -+ width = value64 >> 32; -+ height = value64; -+ -+ if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_FRAME_RATE, NULL))) -+ { -+ if (!default_type || FAILED(hr = IMFMediaType_GetUINT64(default_type, &MF_MT_FRAME_RATE, &value64))) -+ value64 = (UINT64)30000 << 32 | 1001; -+ if (FAILED(hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_RATE, value64))) -+ return hr; -+ } -+ -+ if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_PIXEL_ASPECT_RATIO, NULL))) -+ { -+ if (!default_type || FAILED(hr = IMFMediaType_GetUINT64(default_type, &MF_MT_PIXEL_ASPECT_RATIO, &value64))) -+ value64 = (UINT64)1 << 32 | 1; -+ if (FAILED(hr = IMFMediaType_SetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, value64))) -+ return hr; -+ } -+ -+ if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_SAMPLE_SIZE, NULL))) -+ { -+ if (!default_type || FAILED(hr = IMFMediaType_GetUINT32(default_type, &MF_MT_SAMPLE_SIZE, &value))) -+ { -+ if (IsEqualGUID(&subtype, &MFVideoFormat_YUY2)) -+ value = width * height * 2; -+ else -+ value = width * height * 3 / 2; -+ } -+ if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_SAMPLE_SIZE, value))) -+ return hr; -+ } -+ -+ if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_DEFAULT_STRIDE, NULL))) -+ { -+ if (!default_type || FAILED(hr = IMFMediaType_GetUINT32(default_type, &MF_MT_DEFAULT_STRIDE, &value))) -+ { -+ if (IsEqualGUID(&subtype, &MFVideoFormat_YUY2)) -+ value = width * 2; -+ else -+ value = width; -+ } -+ if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, value))) -+ return hr; -+ } -+ -+ if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_INTERLACE_MODE, NULL))) -+ { -+ if (!default_type || FAILED(hr = IMFMediaType_GetUINT32(default_type, &MF_MT_INTERLACE_MODE, &value))) -+ value = MFVideoInterlace_MixedInterlaceOrProgressive; -+ if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_INTERLACE_MODE, value))) -+ return hr; -+ } -+ -+ if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, NULL))) -+ { -+ if (!default_type || FAILED(hr = IMFMediaType_GetUINT32(default_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value))) -+ value = 1; -+ if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, value))) -+ return hr; -+ } -+ -+ if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_VIDEO_ROTATION, NULL))) -+ { -+ if (!default_type || FAILED(hr = IMFMediaType_GetUINT32(default_type, &MF_MT_VIDEO_ROTATION, &value))) -+ value = 0; -+ if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_VIDEO_ROTATION, value))) -+ return hr; -+ } -+ -+ if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_FIXED_SIZE_SAMPLES, NULL))) -+ { -+ if (!default_type || FAILED(hr = IMFMediaType_GetUINT32(default_type, &MF_MT_FIXED_SIZE_SAMPLES, &value))) -+ value = 1; -+ if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, value))) -+ return hr; -+ } -+ -+ return S_OK; -+} -+ - static HRESULT WINAPI h264_decoder_QueryInterface(IMFTransform *iface, REFIID iid, void **out) - { - struct h264_decoder *decoder = impl_from_IMFTransform(iface); -@@ -170,8 +275,38 @@ static HRESULT WINAPI h264_decoder_GetInputAvailableType(IMFTransform *iface, DW - static HRESULT WINAPI h264_decoder_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index, - IMFMediaType **type) - { -- FIXME("iface %p, id %#lx, index %#lx, type %p stub!\n", iface, id, index, type); -- return E_NOTIMPL; -+ struct h264_decoder *decoder = impl_from_IMFTransform(iface); -+ IMFMediaType *media_type; -+ const GUID *output_type; -+ HRESULT hr; -+ -+ TRACE("iface %p, id %#lx, index %#lx, type %p.\n", iface, id, index, type); -+ -+ if (!decoder->input_type) -+ return MF_E_TRANSFORM_TYPE_NOT_SET; -+ -+ *type = NULL; -+ -+ if (index >= ARRAY_SIZE(h264_decoder_output_types)) -+ return MF_E_NO_MORE_TYPES; -+ output_type = h264_decoder_output_types[index]; -+ -+ if (FAILED(hr = MFCreateMediaType(&media_type))) -+ return hr; -+ -+ if (FAILED(hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video))) -+ goto done; -+ if (FAILED(hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, output_type))) -+ goto done; -+ -+ hr = fill_output_media_type(media_type, NULL); -+ -+done: -+ if (SUCCEEDED(hr)) -+ IMFMediaType_AddRef((*type = media_type)); -+ -+ IMFMediaType_Release(media_type); -+ return hr; - } - - static HRESULT WINAPI h264_decoder_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) -@@ -184,7 +319,7 @@ static HRESULT WINAPI h264_decoder_SetInputType(IMFTransform *iface, DWORD id, I - TRACE("iface %p, id %#lx, type %p, flags %#lx.\n", iface, id, type, flags); - - if (FAILED(hr = IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major)) || -- FAILED(hr = IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype))) -+ FAILED(hr = IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype))) - return E_INVALIDARG; - - if (!IsEqualGUID(&major, &MFMediaType_Video)) --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0071-winegstreamer-Implement-H264-decoder-GetInputAvailab.patch b/patches/mfplat-streaming-support/0071-winegstreamer-Implement-H264-decoder-GetInputAvailab.patch deleted file mode 100644 index 37ec31ac..00000000 --- a/patches/mfplat-streaming-support/0071-winegstreamer-Implement-H264-decoder-GetInputAvailab.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 8b758c937a6e90f16488c0432601ecc98761de5e Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Thu, 10 Feb 2022 09:55:46 +0100 -Subject: [PATCH 71/88] winegstreamer: Implement H264 decoder - GetInputAvailableType. - -Required by Shadow Warrior 2. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183 -CW-Bug-Id: #16839 -CW-Bug-Id: #18678 -CW-Bug-Id: #19362 ---- - dlls/winegstreamer/h264_decoder.c | 23 +++++++++++++++++++++-- - 1 file changed, 21 insertions(+), 2 deletions(-) - -diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c -index 78bf317c36f..7aca79e7a86 100644 ---- a/dlls/winegstreamer/h264_decoder.c -+++ b/dlls/winegstreamer/h264_decoder.c -@@ -268,8 +268,27 @@ static HRESULT WINAPI h264_decoder_AddInputStreams(IMFTransform *iface, DWORD st - static HRESULT WINAPI h264_decoder_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index, - IMFMediaType **type) - { -- FIXME("iface %p, id %#lx, index %#lx, type %p stub!\n", iface, id, index, type); -- return E_NOTIMPL; -+ IMFMediaType *media_type; -+ const GUID *subtype; -+ HRESULT hr; -+ -+ TRACE("iface %p, id %#lx, index %#lx, type %p.\n", iface, id, index, type); -+ -+ *type = NULL; -+ -+ if (index >= ARRAY_SIZE(h264_decoder_input_types)) -+ return MF_E_NO_MORE_TYPES; -+ subtype = h264_decoder_input_types[index]; -+ -+ if (FAILED(hr = MFCreateMediaType(&media_type))) -+ return hr; -+ -+ if (SUCCEEDED(hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video)) && -+ SUCCEEDED(hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, subtype))) -+ IMFMediaType_AddRef((*type = media_type)); -+ -+ IMFMediaType_Release(media_type); -+ return hr; - } - - static HRESULT WINAPI h264_decoder_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index, --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0072-winegstreamer-Implement-H264-decoder-SetOutputType.patch b/patches/mfplat-streaming-support/0072-winegstreamer-Implement-H264-decoder-SetOutputType.patch deleted file mode 100644 index d4fb6485..00000000 --- a/patches/mfplat-streaming-support/0072-winegstreamer-Implement-H264-decoder-SetOutputType.patch +++ /dev/null @@ -1,93 +0,0 @@ -From e1dfb79302e81c47131c820e7ee6182fc929ec22 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Thu, 10 Feb 2022 09:56:08 +0100 -Subject: [PATCH 72/88] winegstreamer: Implement H264 decoder SetOutputType. - -For: Call of Duty III, Mortal Kombat 11, Shadow Warrior 2, -Yakuza 4 Remastered, Hard Reset Redux. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183 -CW-Bug-Id: #16839 -CW-Bug-Id: #18678 -CW-Bug-Id: #19362 ---- - dlls/winegstreamer/h264_decoder.c | 39 +++++++++++++++++++++++++++++-- - 1 file changed, 37 insertions(+), 2 deletions(-) - -diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c -index 7aca79e7a86..2cfc1ac0d05 100644 ---- a/dlls/winegstreamer/h264_decoder.c -+++ b/dlls/winegstreamer/h264_decoder.c -@@ -48,6 +48,7 @@ struct h264_decoder - IMFTransform IMFTransform_iface; - LONG refcount; - IMFMediaType *input_type; -+ IMFMediaType *output_type; - }; - - static struct h264_decoder *impl_from_IMFTransform(IMFTransform *iface) -@@ -192,6 +193,8 @@ static ULONG WINAPI h264_decoder_Release(IMFTransform *iface) - { - if (decoder->input_type) - IMFMediaType_Release(decoder->input_type); -+ if (decoder->output_type) -+ IMFMediaType_Release(decoder->output_type); - free(decoder); - } - -@@ -350,6 +353,12 @@ static HRESULT WINAPI h264_decoder_SetInputType(IMFTransform *iface, DWORD id, I - if (i == ARRAY_SIZE(h264_decoder_input_types)) - return MF_E_INVALIDMEDIATYPE; - -+ if (decoder->output_type) -+ { -+ IMFMediaType_Release(decoder->output_type); -+ decoder->output_type = NULL; -+ } -+ - if (decoder->input_type) - IMFMediaType_Release(decoder->input_type); - IMFMediaType_AddRef((decoder->input_type = type)); -@@ -359,8 +368,34 @@ static HRESULT WINAPI h264_decoder_SetInputType(IMFTransform *iface, DWORD id, I - - static HRESULT WINAPI h264_decoder_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) - { -- FIXME("iface %p, id %#lx, type %p, flags %#lx stub!\n", iface, id, type, flags); -- return E_NOTIMPL; -+ struct h264_decoder *decoder = impl_from_IMFTransform(iface); -+ GUID major, subtype; -+ HRESULT hr; -+ ULONG i; -+ -+ TRACE("iface %p, id %#lx, type %p, flags %#lx.\n", iface, id, type, flags); -+ -+ if (!decoder->input_type) -+ return MF_E_TRANSFORM_TYPE_NOT_SET; -+ -+ if (FAILED(hr = IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major)) || -+ FAILED(hr = IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype))) -+ return hr; -+ -+ if (!IsEqualGUID(&major, &MFMediaType_Video)) -+ return MF_E_INVALIDMEDIATYPE; -+ -+ for (i = 0; i < ARRAY_SIZE(h264_decoder_output_types); ++i) -+ if (IsEqualGUID(&subtype, h264_decoder_output_types[i])) -+ break; -+ if (i == ARRAY_SIZE(h264_decoder_output_types)) -+ return MF_E_INVALIDMEDIATYPE; -+ -+ if (decoder->output_type) -+ IMFMediaType_Release(decoder->output_type); -+ IMFMediaType_AddRef((decoder->output_type = type)); -+ -+ return S_OK; - } - - static HRESULT WINAPI h264_decoder_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0073-winegstreamer-Implement-H264-decoder-GetInputStreamI.patch b/patches/mfplat-streaming-support/0073-winegstreamer-Implement-H264-decoder-GetInputStreamI.patch deleted file mode 100644 index 154b5ff2..00000000 --- a/patches/mfplat-streaming-support/0073-winegstreamer-Implement-H264-decoder-GetInputStreamI.patch +++ /dev/null @@ -1,50 +0,0 @@ -From e186fc28c685facf9bb0c0d1b1e5aee8c9352b30 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Thu, 10 Feb 2022 09:56:23 +0100 -Subject: [PATCH 73/88] winegstreamer: Implement H264 decoder - GetInputStreamInfo. - -For: Call of Duty III, Mortal Kombat 11, Shadow Warrior 2, -Yakuza 4 Remastered, Hard Reset Redux. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183 -CW-Bug-Id: #16839 -CW-Bug-Id: #18678 -CW-Bug-Id: #19362 ---- - dlls/winegstreamer/h264_decoder.c | 16 ++++++++++++++-- - 1 file changed, 14 insertions(+), 2 deletions(-) - -diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c -index 2cfc1ac0d05..1ccb5f39908 100644 ---- a/dlls/winegstreamer/h264_decoder.c -+++ b/dlls/winegstreamer/h264_decoder.c -@@ -225,8 +225,20 @@ static HRESULT WINAPI h264_decoder_GetStreamIDs(IMFTransform *iface, DWORD input - - static HRESULT WINAPI h264_decoder_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info) - { -- FIXME("iface %p, id %#lx, info %p stub!\n", iface, id, info); -- return E_NOTIMPL; -+ struct h264_decoder *decoder = impl_from_IMFTransform(iface); -+ -+ TRACE("iface %p, id %#lx, info %p.\n", iface, id, info); -+ -+ if (!decoder->input_type) -+ return MF_E_TRANSFORM_TYPE_NOT_SET; -+ -+ info->hnsMaxLatency = 0; -+ info->dwFlags = MFT_INPUT_STREAM_WHOLE_SAMPLES | MFT_INPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER | MFT_INPUT_STREAM_FIXED_SAMPLE_SIZE; -+ info->cbSize = 0x1000; -+ info->cbMaxLookahead = 0; -+ info->cbAlignment = 0; -+ -+ return S_OK; - } - - static HRESULT WINAPI h264_decoder_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info) --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0074-winegstreamer-Implement-H264-decoder-GetOutputStream.patch b/patches/mfplat-streaming-support/0074-winegstreamer-Implement-H264-decoder-GetOutputStream.patch deleted file mode 100644 index 0fcbc317..00000000 --- a/patches/mfplat-streaming-support/0074-winegstreamer-Implement-H264-decoder-GetOutputStream.patch +++ /dev/null @@ -1,55 +0,0 @@ -From a0aa60794e90bd635983dfb7158ba19bdb4e3485 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Thu, 10 Feb 2022 09:56:35 +0100 -Subject: [PATCH 74/88] winegstreamer: Implement H264 decoder - GetOutputStreamInfo. - -For: Call of Duty III, Mortal Kombat 11, Shadow Warrior 2, -Yakuza 4 Remastered, Hard Reset Redux. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183 -CW-Bug-Id: #16839 -CW-Bug-Id: #18678 -CW-Bug-Id: #19362 ---- - dlls/winegstreamer/h264_decoder.c | 21 +++++++++++++++++++-- - 1 file changed, 19 insertions(+), 2 deletions(-) - -diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c -index 1ccb5f39908..eadb28cdaaa 100644 ---- a/dlls/winegstreamer/h264_decoder.c -+++ b/dlls/winegstreamer/h264_decoder.c -@@ -243,8 +243,25 @@ static HRESULT WINAPI h264_decoder_GetInputStreamInfo(IMFTransform *iface, DWORD - - static HRESULT WINAPI h264_decoder_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info) - { -- FIXME("iface %p, id %#lx, info %p stub!\n", iface, id, info); -- return E_NOTIMPL; -+ struct h264_decoder *decoder = impl_from_IMFTransform(iface); -+ IMFMediaType *media_type; -+ UINT32 sample_size; -+ HRESULT hr; -+ -+ TRACE("iface %p, id %#lx, info %p.\n", iface, id, info); -+ -+ if (!decoder->input_type || !decoder->output_type) -+ return MF_E_TRANSFORM_TYPE_NOT_SET; -+ -+ media_type = decoder->output_type; -+ -+ info->dwFlags = MFT_OUTPUT_STREAM_WHOLE_SAMPLES | MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER | MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE; -+ if (FAILED(hr = IMFMediaType_GetUINT32(media_type, &MF_MT_SAMPLE_SIZE, &sample_size))) -+ sample_size = 1920 * 1080 * 2; -+ info->cbSize = sample_size; -+ info->cbAlignment = 0; -+ -+ return S_OK; - } - - static HRESULT WINAPI h264_decoder_GetAttributes(IMFTransform *iface, IMFAttributes **attributes) --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0075-winegstreamer-Add-H264-encoded-format-support-in-wg_.patch b/patches/mfplat-streaming-support/0075-winegstreamer-Add-H264-encoded-format-support-in-wg_.patch deleted file mode 100644 index dc98fe86..00000000 --- a/patches/mfplat-streaming-support/0075-winegstreamer-Add-H264-encoded-format-support-in-wg_.patch +++ /dev/null @@ -1,264 +0,0 @@ -From b3ce2fcb76da45fbf1683cbd518172eae8d8d277 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Fri, 21 Jan 2022 14:33:39 +0100 -Subject: [PATCH 75/88] winegstreamer: Add H264 encoded format support in - wg_transform. - -For: Call of Duty III, Mortal Kombat 11, Shadow Warrior 2, -Yakuza 4 Remastered, Hard Reset Redux. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183 -CW-Bug-Id: #16839 -CW-Bug-Id: #18678 -CW-Bug-Id: #19362 ---- - dlls/winegstreamer/h264_decoder.c | 36 +++++++++++++++++- - dlls/winegstreamer/mfplat.c | 37 ++++++++++++++++++ - dlls/winegstreamer/unixlib.h | 8 ++++ - dlls/winegstreamer/wg_transform.c | 63 +++++++++++++++++++++++++++++++ - 4 files changed, 143 insertions(+), 1 deletion(-) - -diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c -index eadb28cdaaa..b7de097fc7d 100644 ---- a/dlls/winegstreamer/h264_decoder.c -+++ b/dlls/winegstreamer/h264_decoder.c -@@ -49,6 +49,8 @@ struct h264_decoder - LONG refcount; - IMFMediaType *input_type; - IMFMediaType *output_type; -+ -+ struct wg_transform *wg_transform; - }; - - static struct h264_decoder *impl_from_IMFTransform(IMFTransform *iface) -@@ -56,6 +58,30 @@ static struct h264_decoder *impl_from_IMFTransform(IMFTransform *iface) - return CONTAINING_RECORD(iface, struct h264_decoder, IMFTransform_iface); - } - -+static HRESULT try_create_wg_transform(struct h264_decoder *decoder) -+{ -+ struct wg_encoded_format input_format; -+ struct wg_format output_format; -+ -+ if (decoder->wg_transform) -+ wg_transform_destroy(decoder->wg_transform); -+ -+ mf_media_type_to_wg_encoded_format(decoder->input_type, &input_format); -+ if (input_format.encoded_type == WG_ENCODED_TYPE_UNKNOWN) -+ return MF_E_INVALIDMEDIATYPE; -+ -+ mf_media_type_to_wg_format(decoder->output_type, &output_format); -+ if (output_format.major_type == WG_MAJOR_TYPE_UNKNOWN) -+ return MF_E_INVALIDMEDIATYPE; -+ -+ decoder->wg_transform = wg_transform_create(&input_format, &output_format); -+ if (decoder->wg_transform) -+ return S_OK; -+ -+ WARN("Failed to create H264 wg_transform.\n"); -+ return E_FAIL; -+} -+ - static HRESULT fill_output_media_type(IMFMediaType *media_type, IMFMediaType *default_type) - { - UINT32 value, width, height; -@@ -191,6 +217,8 @@ static ULONG WINAPI h264_decoder_Release(IMFTransform *iface) - - if (!refcount) - { -+ if (decoder->wg_transform) -+ wg_transform_destroy(decoder->wg_transform); - if (decoder->input_type) - IMFMediaType_Release(decoder->input_type); - if (decoder->output_type) -@@ -424,7 +452,13 @@ static HRESULT WINAPI h264_decoder_SetOutputType(IMFTransform *iface, DWORD id, - IMFMediaType_Release(decoder->output_type); - IMFMediaType_AddRef((decoder->output_type = type)); - -- return S_OK; -+ if (FAILED(hr = try_create_wg_transform(decoder))) -+ { -+ IMFMediaType_Release(decoder->output_type); -+ decoder->output_type = NULL; -+ } -+ -+ return hr; - } - - static HRESULT WINAPI h264_decoder_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) -diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c -index ca26c767125..f2cdd04070d 100644 ---- a/dlls/winegstreamer/mfplat.c -+++ b/dlls/winegstreamer/mfplat.c -@@ -938,6 +938,36 @@ static void mf_media_type_to_wg_encoded_format_xwma(IMFMediaType *type, struct w - memcpy(format->u.xwma.codec_data, codec_data, codec_data_len); - } - -+static void mf_media_type_to_wg_encoded_format_h264(IMFMediaType *type, struct wg_encoded_format *format) -+{ -+ UINT64 frame_rate, frame_size; -+ UINT32 profile, level; -+ -+ format->encoded_type = WG_ENCODED_TYPE_H264; -+ format->u.h264.width = 0; -+ format->u.h264.height = 0; -+ format->u.h264.fps_n = 1; -+ format->u.h264.fps_d = 1; -+ -+ if (SUCCEEDED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size))) -+ { -+ format->u.h264.width = (UINT32)(frame_size >> 32); -+ format->u.h264.height = (UINT32)frame_size; -+ } -+ -+ if (SUCCEEDED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_RATE, &frame_rate)) && (UINT32)frame_rate) -+ { -+ format->u.h264.fps_n = (UINT32)(frame_rate >> 32); -+ format->u.h264.fps_d = (UINT32)frame_rate; -+ } -+ -+ if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_MPEG2_PROFILE, &profile))) -+ format->u.h264.profile = profile; -+ -+ if (SUCCEEDED(IMFMediaType_GetUINT32(type, &MF_MT_MPEG2_LEVEL, &level))) -+ format->u.h264.level = level; -+} -+ - void mf_media_type_to_wg_encoded_format(IMFMediaType *type, struct wg_encoded_format *format) - { - GUID major_type, subtype; -@@ -970,6 +1000,13 @@ void mf_media_type_to_wg_encoded_format(IMFMediaType *type, struct wg_encoded_fo - else - FIXME("Unimplemented audio subtype %s.\n", debugstr_guid(&subtype)); - } -+ else if (IsEqualGUID(&major_type, &MFMediaType_Video)) -+ { -+ if (IsEqualGUID(&subtype, &MFVideoFormat_H264)) -+ mf_media_type_to_wg_encoded_format_h264(type, format); -+ else -+ FIXME("Unimplemented audio subtype %s.\n", debugstr_guid(&subtype)); -+ } - else - { - FIXME("Unimplemented major type %s.\n", debugstr_guid(&major_type)); -diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h -index 0df245408ee..84564008ee2 100644 ---- a/dlls/winegstreamer/unixlib.h -+++ b/dlls/winegstreamer/unixlib.h -@@ -132,6 +132,7 @@ struct wg_encoded_format - WG_ENCODED_TYPE_UNKNOWN, - WG_ENCODED_TYPE_WMA, - WG_ENCODED_TYPE_XMA, -+ WG_ENCODED_TYPE_H264, - } encoded_type; - - union -@@ -147,6 +148,13 @@ struct wg_encoded_format - uint32_t codec_data_len; - unsigned char codec_data[64]; - } xwma; -+ struct -+ { -+ int32_t width, height; -+ uint32_t fps_n, fps_d; -+ uint32_t profile; -+ uint32_t level; -+ } h264; - } u; - }; - -diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c -index 256e77429a0..2956ddf753b 100644 ---- a/dlls/winegstreamer/wg_transform.c -+++ b/dlls/winegstreamer/wg_transform.c -@@ -98,6 +98,64 @@ static GstCaps *wg_format_to_caps_xwma(const struct wg_encoded_format *format) - return caps; - } - -+static GstCaps *wg_format_to_caps_h264(const struct wg_encoded_format *format) -+{ -+ const char *profile, *level; -+ GstCaps *caps; -+ -+ caps = gst_caps_new_empty_simple("video/x-h264"); -+ gst_caps_set_simple(caps, "stream-format", G_TYPE_STRING, "byte-stream", NULL); -+ gst_caps_set_simple(caps, "alignment", G_TYPE_STRING, "au", NULL); -+ -+ if (format->u.h264.width) -+ gst_caps_set_simple(caps, "width", G_TYPE_INT, format->u.h264.width, NULL); -+ if (format->u.h264.height) -+ gst_caps_set_simple(caps, "height", G_TYPE_INT, format->u.h264.height, NULL); -+ if (format->u.h264.fps_n || format->u.h264.fps_d) -+ gst_caps_set_simple(caps, "framerate", GST_TYPE_FRACTION, format->u.h264.fps_n, format->u.h264.fps_d, NULL); -+ -+ switch (format->u.h264.profile) -+ { -+ case /* eAVEncH264VProfile_Main */ 77: profile = "main"; break; -+ case /* eAVEncH264VProfile_High */ 100: profile = "high"; break; -+ case /* eAVEncH264VProfile_444 */ 244: profile = "high-4:4:4"; break; -+ default: -+ GST_ERROR("Unrecognized H.264 profile attribute %u.", format->u.h264.profile); -+ /* fallthrough */ -+ case 0: profile = NULL; -+ } -+ if (profile) -+ gst_caps_set_simple(caps, "profile", G_TYPE_STRING, profile, NULL); -+ -+ switch (format->u.h264.level) -+ { -+ case /* eAVEncH264VLevel1 */ 10: level = "1"; break; -+ case /* eAVEncH264VLevel1_1 */ 11: level = "1.1"; break; -+ case /* eAVEncH264VLevel1_2 */ 12: level = "1.2"; break; -+ case /* eAVEncH264VLevel1_3 */ 13: level = "1.3"; break; -+ case /* eAVEncH264VLevel2 */ 20: level = "2"; break; -+ case /* eAVEncH264VLevel2_1 */ 21: level = "2.1"; break; -+ case /* eAVEncH264VLevel2_2 */ 22: level = "2.2"; break; -+ case /* eAVEncH264VLevel3 */ 30: level = "3"; break; -+ case /* eAVEncH264VLevel3_1 */ 31: level = "3.1"; break; -+ case /* eAVEncH264VLevel3_2 */ 32: level = "3.2"; break; -+ case /* eAVEncH264VLevel4 */ 40: level = "4"; break; -+ case /* eAVEncH264VLevel4_1 */ 41: level = "4.1"; break; -+ case /* eAVEncH264VLevel4_2 */ 42: level = "4.2"; break; -+ case /* eAVEncH264VLevel5 */ 50: level = "5"; break; -+ case /* eAVEncH264VLevel5_1 */ 51: level = "5.1"; break; -+ case /* eAVEncH264VLevel5_2 */ 52: level = "5.2"; break; -+ default: -+ GST_ERROR("Unrecognized H.264 level attribute %u.", format->u.h264.level); -+ /* fallthrough */ -+ case 0: level = NULL; -+ } -+ if (level) -+ gst_caps_set_simple(caps, "level", G_TYPE_STRING, level, NULL); -+ -+ return caps; -+} -+ - static GstCaps *wg_encoded_format_to_caps(const struct wg_encoded_format *format) - { - switch (format->encoded_type) -@@ -107,6 +165,8 @@ static GstCaps *wg_encoded_format_to_caps(const struct wg_encoded_format *format - case WG_ENCODED_TYPE_WMA: - case WG_ENCODED_TYPE_XMA: - return wg_format_to_caps_xwma(format); -+ case WG_ENCODED_TYPE_H264: -+ return wg_format_to_caps_h264(format); - } - assert(0); - return NULL; -@@ -286,7 +346,10 @@ NTSTATUS wg_transform_create(void *args) - !transform_append_element(transform, element, &first, &last)) - goto failed; - break; -+ case WG_MAJOR_TYPE_VIDEO: -+ break; - default: -+ assert(0); - break; - } - --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0076-winegstreamer-Implement-H264-decoder-ProcessInput.patch b/patches/mfplat-streaming-support/0076-winegstreamer-Implement-H264-decoder-ProcessInput.patch deleted file mode 100644 index 9b82e76f..00000000 --- a/patches/mfplat-streaming-support/0076-winegstreamer-Implement-H264-decoder-ProcessInput.patch +++ /dev/null @@ -1,63 +0,0 @@ -From ae960b62a8e83ea1f14ac04acd876c00c4ae0b7f Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Thu, 10 Feb 2022 09:56:47 +0100 -Subject: [PATCH 76/88] winegstreamer: Implement H264 decoder ProcessInput. - -For: Call of Duty III, Mortal Kombat 11, Shadow Warrior 2, -Yakuza 4 Remastered, Hard Reset Redux. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183 -CW-Bug-Id: #16839 -CW-Bug-Id: #18678 -CW-Bug-Id: #19362 ---- - dlls/winegstreamer/h264_decoder.c | 30 ++++++++++++++++++++++++++++-- - 1 file changed, 28 insertions(+), 2 deletions(-) - -diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c -index b7de097fc7d..268262a0f18 100644 ---- a/dlls/winegstreamer/h264_decoder.c -+++ b/dlls/winegstreamer/h264_decoder.c -@@ -506,8 +506,34 @@ static HRESULT WINAPI h264_decoder_ProcessMessage(IMFTransform *iface, MFT_MESSA - - static HRESULT WINAPI h264_decoder_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags) - { -- FIXME("iface %p, id %#lx, sample %p, flags %#lx stub!\n", iface, id, sample, flags); -- return E_NOTIMPL; -+ struct h264_decoder *decoder = impl_from_IMFTransform(iface); -+ IMFMediaBuffer *media_buffer; -+ MFT_INPUT_STREAM_INFO info; -+ DWORD buffer_size; -+ BYTE *buffer; -+ HRESULT hr; -+ -+ TRACE("iface %p, id %#lx, sample %p, flags %#lx.\n", iface, id, sample, flags); -+ -+ if (FAILED(hr = IMFTransform_GetInputStreamInfo(iface, 0, &info))) -+ return hr; -+ -+ if (!decoder->wg_transform) -+ return MF_E_TRANSFORM_TYPE_NOT_SET; -+ -+ if (FAILED(hr = IMFSample_ConvertToContiguousBuffer(sample, &media_buffer))) -+ return hr; -+ -+ if (FAILED(hr = IMFMediaBuffer_Lock(media_buffer, &buffer, NULL, &buffer_size))) -+ goto done; -+ -+ hr = wg_transform_push_data(decoder->wg_transform, buffer, buffer_size); -+ -+ IMFMediaBuffer_Unlock(media_buffer); -+ -+done: -+ IMFMediaBuffer_Release(media_buffer); -+ return hr; - } - - static HRESULT WINAPI h264_decoder_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count, --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0077-winegstreamer-Implement-H264-decoder-ProcessOutput.patch b/patches/mfplat-streaming-support/0077-winegstreamer-Implement-H264-decoder-ProcessOutput.patch deleted file mode 100644 index cab0f41d..00000000 --- a/patches/mfplat-streaming-support/0077-winegstreamer-Implement-H264-decoder-ProcessOutput.patch +++ /dev/null @@ -1,83 +0,0 @@ -From 9509bc29d7a6d0514f2573007b2aa3399f4d2095 Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Thu, 10 Feb 2022 09:57:10 +0100 -Subject: [PATCH 77/88] winegstreamer: Implement H264 decoder ProcessOutput. - -For: Call of Duty III, Mortal Kombat 11, Shadow Warrior 2, -Yakuza 4 Remastered, Hard Reset Redux. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183 -CW-Bug-Id: #16839 -CW-Bug-Id: #18678 -CW-Bug-Id: #19362 ---- - dlls/winegstreamer/h264_decoder.c | 50 +++++++++++++++++++++++++++++-- - 1 file changed, 48 insertions(+), 2 deletions(-) - -diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c -index 268262a0f18..44d55ae061f 100644 ---- a/dlls/winegstreamer/h264_decoder.c -+++ b/dlls/winegstreamer/h264_decoder.c -@@ -539,8 +539,54 @@ done: - static HRESULT WINAPI h264_decoder_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count, - MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status) - { -- FIXME("iface %p, flags %#lx, count %lu, samples %p, status %p stub!\n", iface, flags, count, samples, status); -- return E_NOTIMPL; -+ struct h264_decoder *decoder = impl_from_IMFTransform(iface); -+ struct wg_sample wg_sample = {0}; -+ IMFMediaBuffer *media_buffer; -+ MFT_OUTPUT_STREAM_INFO info; -+ DWORD buffer_size; -+ HRESULT hr; -+ -+ TRACE("iface %p, flags %#lx, count %lu, samples %p, status %p.\n", iface, flags, count, samples, status); -+ -+ if (count > 1) -+ { -+ FIXME("Not implemented count %lu\n", count); -+ return E_NOTIMPL; -+ } -+ -+ if (FAILED(hr = IMFTransform_GetOutputStreamInfo(iface, 0, &info))) -+ return hr; -+ -+ if (!decoder->wg_transform) -+ return MF_E_TRANSFORM_TYPE_NOT_SET; -+ -+ *status = 0; -+ samples[0].dwStatus = 0; -+ if (!samples[0].pSample) -+ { -+ samples[0].dwStatus = MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE; -+ return MF_E_TRANSFORM_NEED_MORE_INPUT; -+ } -+ -+ if (FAILED(hr = IMFSample_ConvertToContiguousBuffer(samples[0].pSample, &media_buffer))) -+ return hr; -+ -+ if (FAILED(hr = IMFMediaBuffer_Lock(media_buffer, &wg_sample.data, &buffer_size, NULL))) -+ goto done; -+ wg_sample.size = buffer_size; -+ -+ if (wg_sample.size < info.cbSize) -+ hr = MF_E_BUFFERTOOSMALL; -+ else if (SUCCEEDED(hr = wg_transform_read_data(decoder->wg_transform, &wg_sample))) -+ hr = IMFMediaBuffer_SetCurrentLength(media_buffer, wg_sample.size); -+ -+ IMFMediaBuffer_Unlock(media_buffer); -+ -+done: -+ if (FAILED(hr)) -+ IMFMediaBuffer_SetCurrentLength(media_buffer, 0); -+ IMFMediaBuffer_Release(media_buffer); -+ return hr; - } - - static const IMFTransformVtbl h264_decoder_vtbl = --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0078-winegstreamer-Add-timestamps-and-duration-to-H264-de.patch b/patches/mfplat-streaming-support/0078-winegstreamer-Add-timestamps-and-duration-to-H264-de.patch deleted file mode 100644 index 70191c33..00000000 --- a/patches/mfplat-streaming-support/0078-winegstreamer-Add-timestamps-and-duration-to-H264-de.patch +++ /dev/null @@ -1,87 +0,0 @@ -From 1ddbede0757008fc9db91f03f0fbc1c671822b9b Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Fri, 21 Jan 2022 14:34:12 +0100 -Subject: [PATCH 78/88] winegstreamer: Add timestamps and duration to H264 - decoded samples. - -For: Call of Duty III, Mortal Kombat 11, Shadow Warrior 2, -Yakuza 4 Remastered, Hard Reset Redux. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183 -CW-Bug-Id: #16839 -CW-Bug-Id: #18678 -CW-Bug-Id: #19362 ---- - dlls/winegstreamer/h264_decoder.c | 6 ++++++ - dlls/winegstreamer/unixlib.h | 4 ++++ - dlls/winegstreamer/wg_transform.c | 11 +++++++++++ - 3 files changed, 21 insertions(+) - -diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c -index 44d55ae061f..69e747f1dc0 100644 ---- a/dlls/winegstreamer/h264_decoder.c -+++ b/dlls/winegstreamer/h264_decoder.c -@@ -578,7 +578,13 @@ static HRESULT WINAPI h264_decoder_ProcessOutput(IMFTransform *iface, DWORD flag - if (wg_sample.size < info.cbSize) - hr = MF_E_BUFFERTOOSMALL; - else if (SUCCEEDED(hr = wg_transform_read_data(decoder->wg_transform, &wg_sample))) -+ { -+ if (wg_sample.flags & WG_SAMPLE_FLAG_HAS_PTS) -+ IMFSample_SetSampleTime(samples[0].pSample, wg_sample.pts); -+ if (wg_sample.flags & WG_SAMPLE_FLAG_HAS_DURATION) -+ IMFSample_SetSampleDuration(samples[0].pSample, wg_sample.duration); - hr = IMFMediaBuffer_SetCurrentLength(media_buffer, wg_sample.size); -+ } - - IMFMediaBuffer_Unlock(media_buffer); - -diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h -index 84564008ee2..543e92e6c0d 100644 ---- a/dlls/winegstreamer/unixlib.h -+++ b/dlls/winegstreamer/unixlib.h -@@ -329,6 +329,8 @@ struct wg_transform_push_data_params - enum wg_sample_flags - { - WG_SAMPLE_FLAG_INCOMPLETE = 1, -+ WG_SAMPLE_FLAG_HAS_PTS = 2, -+ WG_SAMPLE_FLAG_HAS_DURATION = 4, - }; - - struct wg_sample -@@ -336,6 +338,8 @@ struct wg_sample - UINT32 flags; - BYTE *data; - UINT32 size; -+ /* pts and duration are in 100-nanosecond units. */ -+ ULONGLONG pts, duration; - }; - - struct wg_transform_read_data_params -diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c -index 2956ddf753b..93e777ba39a 100644 ---- a/dlls/winegstreamer/wg_transform.c -+++ b/dlls/winegstreamer/wg_transform.c -@@ -489,6 +489,17 @@ NTSTATUS wg_transform_read_data(void *args) - memcpy(read_sample->data, info.data, read_sample->size); - gst_buffer_unmap(buffer, &info); - -+ if (buffer->pts != GST_CLOCK_TIME_NONE) -+ { -+ read_sample->flags |= WG_SAMPLE_FLAG_HAS_PTS; -+ read_sample->pts = buffer->pts / 100; -+ } -+ if (buffer->duration != GST_CLOCK_TIME_NONE) -+ { -+ read_sample->flags |= WG_SAMPLE_FLAG_HAS_DURATION; -+ read_sample->duration = buffer->duration / 100; -+ } -+ - if (info.size > read_sample->size) - { - read_sample->flags |= WG_SAMPLE_FLAG_INCOMPLETE; --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0079-winegstreamer-Support-dynamic-wg_transform-video-for.patch b/patches/mfplat-streaming-support/0079-winegstreamer-Support-dynamic-wg_transform-video-for.patch deleted file mode 100644 index aec4f63a..00000000 --- a/patches/mfplat-streaming-support/0079-winegstreamer-Support-dynamic-wg_transform-video-for.patch +++ /dev/null @@ -1,285 +0,0 @@ -From af85dd52165d0c5755a34c7df87cbc631c92efcc Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Thu, 10 Feb 2022 09:57:36 +0100 -Subject: [PATCH 79/88] winegstreamer: Support dynamic wg_transform video - format change. - -For: Call of Duty III, Mortal Kombat 11, Shadow Warrior 2, -Yakuza 4 Remastered, Hard Reset Redux. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183 -CW-Bug-Id: #16839 -CW-Bug-Id: #18678 -CW-Bug-Id: #19362 ---- - dlls/winegstreamer/h264_decoder.c | 26 ++++++++++++- - dlls/winegstreamer/unix_private.h | 2 + - dlls/winegstreamer/unixlib.h | 1 + - dlls/winegstreamer/wg_parser.c | 4 +- - dlls/winegstreamer/wg_transform.c | 61 ++++++++++++++++++++++++++++++- - 5 files changed, 89 insertions(+), 5 deletions(-) - -diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c -index 69e747f1dc0..219790128da 100644 ---- a/dlls/winegstreamer/h264_decoder.c -+++ b/dlls/winegstreamer/h264_decoder.c -@@ -51,6 +51,7 @@ struct h264_decoder - IMFMediaType *output_type; - - struct wg_transform *wg_transform; -+ struct wg_format wg_format; - }; - - static struct h264_decoder *impl_from_IMFTransform(IMFTransform *iface) -@@ -378,7 +379,7 @@ static HRESULT WINAPI h264_decoder_GetOutputAvailableType(IMFTransform *iface, D - if (FAILED(hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, output_type))) - goto done; - -- hr = fill_output_media_type(media_type, NULL); -+ hr = fill_output_media_type(media_type, decoder->output_type); - - done: - if (SUCCEEDED(hr)) -@@ -427,6 +428,7 @@ static HRESULT WINAPI h264_decoder_SetOutputType(IMFTransform *iface, DWORD id, - { - struct h264_decoder *decoder = impl_from_IMFTransform(iface); - GUID major, subtype; -+ BOOL identical; - HRESULT hr; - ULONG i; - -@@ -449,7 +451,13 @@ static HRESULT WINAPI h264_decoder_SetOutputType(IMFTransform *iface, DWORD id, - return MF_E_INVALIDMEDIATYPE; - - if (decoder->output_type) -+ { -+ if (SUCCEEDED(hr = IMFMediaType_Compare(decoder->output_type, (IMFAttributes *)type, -+ MF_ATTRIBUTES_MATCH_THEIR_ITEMS, &identical)) && identical) -+ return S_OK; - IMFMediaType_Release(decoder->output_type); -+ } -+ - IMFMediaType_AddRef((decoder->output_type = type)); - - if (FAILED(hr = try_create_wg_transform(decoder))) -@@ -543,6 +551,7 @@ static HRESULT WINAPI h264_decoder_ProcessOutput(IMFTransform *iface, DWORD flag - struct wg_sample wg_sample = {0}; - IMFMediaBuffer *media_buffer; - MFT_OUTPUT_STREAM_INFO info; -+ IMFMediaType *media_type; - DWORD buffer_size; - HRESULT hr; - -@@ -575,6 +584,7 @@ static HRESULT WINAPI h264_decoder_ProcessOutput(IMFTransform *iface, DWORD flag - goto done; - wg_sample.size = buffer_size; - -+ wg_sample.format = &decoder->wg_format; - if (wg_sample.size < info.cbSize) - hr = MF_E_BUFFERTOOSMALL; - else if (SUCCEEDED(hr = wg_transform_read_data(decoder->wg_transform, &wg_sample))) -@@ -585,6 +595,20 @@ static HRESULT WINAPI h264_decoder_ProcessOutput(IMFTransform *iface, DWORD flag - IMFSample_SetSampleDuration(samples[0].pSample, wg_sample.duration); - hr = IMFMediaBuffer_SetCurrentLength(media_buffer, wg_sample.size); - } -+ else if (hr == MF_E_TRANSFORM_STREAM_CHANGE) -+ { -+ media_type = mf_media_type_from_wg_format(&decoder->wg_format); -+ IMFMediaType_SetUINT32(media_type, &MF_MT_SAMPLE_SIZE, wg_sample.size); -+ IMFMediaType_DeleteItem(media_type, &MF_MT_FRAME_RATE); -+ IMFMediaType_DeleteItem(decoder->output_type, &MF_MT_DEFAULT_STRIDE); -+ fill_output_media_type(media_type, decoder->output_type); -+ -+ IMFMediaType_Release(decoder->output_type); -+ decoder->output_type = media_type; -+ -+ samples[0].dwStatus |= MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE; -+ *status |= MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE; -+ } - - IMFMediaBuffer_Unlock(media_buffer); - -diff --git a/dlls/winegstreamer/unix_private.h b/dlls/winegstreamer/unix_private.h -index 1b055436ba5..88566ab1db5 100644 ---- a/dlls/winegstreamer/unix_private.h -+++ b/dlls/winegstreamer/unix_private.h -@@ -26,6 +26,8 @@ - extern bool init_gstreamer(void) DECLSPEC_HIDDEN; - extern GstElement *create_element(const char *name, const char *plugin_set) DECLSPEC_HIDDEN; - extern GstCaps *wg_format_to_caps(const struct wg_format *format) DECLSPEC_HIDDEN; -+extern void wg_format_from_caps(struct wg_format *format, const GstCaps *caps) DECLSPEC_HIDDEN; -+extern bool wg_format_compare(const struct wg_format *a, const struct wg_format *b) DECLSPEC_HIDDEN; - - extern NTSTATUS wg_transform_create(void *args) DECLSPEC_HIDDEN; - extern NTSTATUS wg_transform_destroy(void *args) DECLSPEC_HIDDEN; -diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h -index 543e92e6c0d..1beeed8f1a2 100644 ---- a/dlls/winegstreamer/unixlib.h -+++ b/dlls/winegstreamer/unixlib.h -@@ -340,6 +340,7 @@ struct wg_sample - UINT32 size; - /* pts and duration are in 100-nanosecond units. */ - ULONGLONG pts, duration; -+ struct wg_format *format; - }; - - struct wg_transform_read_data_params -diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index 3217c78e864..8e64735bd64 100644 ---- a/dlls/winegstreamer/wg_parser.c -+++ b/dlls/winegstreamer/wg_parser.c -@@ -311,7 +311,7 @@ static void wg_format_from_caps_video_cinepak(struct wg_format *format, const Gs - format->u.video.fps_d = fps_d; - } - --static void wg_format_from_caps(struct wg_format *format, const GstCaps *caps) -+void wg_format_from_caps(struct wg_format *format, const GstCaps *caps) - { - const GstStructure *structure = gst_caps_get_structure(caps, 0); - const char *name = gst_structure_get_name(structure); -@@ -556,7 +556,7 @@ GstCaps *wg_format_to_caps(const struct wg_format *format) - return NULL; - } - --static bool wg_format_compare(const struct wg_format *a, const struct wg_format *b) -+bool wg_format_compare(const struct wg_format *a, const struct wg_format *b) - { - if (a->major_type != b->major_type) - return false; -diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c -index 93e777ba39a..df37b4e8543 100644 ---- a/dlls/winegstreamer/wg_transform.c -+++ b/dlls/winegstreamer/wg_transform.c -@@ -56,6 +56,7 @@ struct wg_transform - GstPad *their_sink, *their_src; - pthread_mutex_t mutex; - struct list samples; -+ GstCaps *sink_caps; - }; - - static GstCaps *wg_format_to_caps_xwma(const struct wg_encoded_format *format) -@@ -184,7 +185,7 @@ static GstFlowReturn transform_sink_chain_cb(GstPad *pad, GstObject *parent, Gst - else - { - pthread_mutex_lock(&transform->mutex); -- if (!(sample->sample = gst_sample_new(buffer, NULL, NULL, NULL))) -+ if (!(sample->sample = gst_sample_new(buffer, transform->sink_caps, NULL, NULL))) - GST_ERROR("Failed to allocate transform sample"); - list_add_tail(&transform->samples, &sample->entry); - pthread_mutex_unlock(&transform->mutex); -@@ -194,6 +195,38 @@ static GstFlowReturn transform_sink_chain_cb(GstPad *pad, GstObject *parent, Gst - return GST_FLOW_OK; - } - -+static gboolean transform_sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) -+{ -+ struct wg_transform *transform = gst_pad_get_element_private(pad); -+ -+ GST_INFO("transform %p, type \"%s\".", transform, GST_EVENT_TYPE_NAME(event)); -+ -+ switch (event->type) -+ { -+ case GST_EVENT_CAPS: -+ { -+ GstCaps *caps; -+ gchar *str; -+ -+ gst_event_parse_caps(event, &caps); -+ str = gst_caps_to_string(caps); -+ GST_WARNING("Got caps \"%s\".", str); -+ g_free(str); -+ -+ pthread_mutex_lock(&transform->mutex); -+ gst_caps_unref(transform->sink_caps); -+ transform->sink_caps = gst_caps_ref(caps); -+ pthread_mutex_unlock(&transform->mutex); -+ break; -+ } -+ default: -+ GST_WARNING("Ignoring \"%s\" event.", GST_EVENT_TYPE_NAME(event)); -+ } -+ -+ gst_event_unref(event); -+ return TRUE; -+} -+ - NTSTATUS wg_transform_destroy(void *args) - { - struct wg_transform *transform = args; -@@ -311,7 +344,7 @@ NTSTATUS wg_transform_create(void *args) - GstPadTemplate *template; - const gchar *media_type; - GstSegment *segment; -- int ret; -+ int i, ret; - - if (!init_gstreamer()) - return E_FAIL; -@@ -329,6 +362,7 @@ NTSTATUS wg_transform_create(void *args) - raw_caps = gst_caps_new_empty_simple(media_type); - assert(raw_caps); - -+ transform->sink_caps = gst_caps_copy(sink_caps); - transform->container = gst_bin_new("wg_transform"); - assert(transform->container); - -@@ -347,6 +381,12 @@ NTSTATUS wg_transform_create(void *args) - goto failed; - break; - case WG_MAJOR_TYPE_VIDEO: -+ if (!(element = create_element("videoconvert", "base")) || -+ !transform_append_element(transform, element, &first, &last)) -+ goto failed; -+ for (i = 0; i < gst_caps_get_size(sink_caps); ++i) -+ gst_structure_remove_fields(gst_caps_get_structure(sink_caps, i), -+ "width", "height", NULL); - break; - default: - assert(0); -@@ -377,6 +417,7 @@ NTSTATUS wg_transform_create(void *args) - assert(transform->my_sink); - - gst_pad_set_element_private(transform->my_sink, transform); -+ gst_pad_set_event_function(transform->my_sink, transform_sink_event_cb); - gst_pad_set_chain_function(transform->my_sink, transform_sink_chain_cb); - - if ((ret = gst_pad_link(transform->my_src, transform->their_sink)) < 0) -@@ -469,9 +510,11 @@ NTSTATUS wg_transform_read_data(void *args) - struct wg_transform *transform = params->transform; - struct wg_sample *read_sample = params->sample; - struct wg_transform_sample *transform_sample; -+ struct wg_format buffer_format; - GstBuffer *buffer; - struct list *head; - GstMapInfo info; -+ GstCaps *caps; - - pthread_mutex_lock(&transform->mutex); - if (!(head = list_head(&transform->samples))) -@@ -483,6 +526,20 @@ NTSTATUS wg_transform_read_data(void *args) - transform_sample = LIST_ENTRY(head, struct wg_transform_sample, entry); - buffer = gst_sample_get_buffer(transform_sample->sample); - -+ if (read_sample->format) -+ { -+ if (!(caps = gst_sample_get_caps(transform_sample->sample))) -+ caps = transform->sink_caps; -+ wg_format_from_caps(&buffer_format, caps); -+ if (!wg_format_compare(read_sample->format, &buffer_format)) -+ { -+ *read_sample->format = buffer_format; -+ read_sample->size = gst_buffer_get_size(buffer); -+ pthread_mutex_unlock(&transform->mutex); -+ return MF_E_TRANSFORM_STREAM_CHANGE; -+ } -+ } -+ - gst_buffer_map(buffer, &info, GST_MAP_READ); - if (read_sample->size > info.size) - read_sample->size = info.size; --- -2.34.1 - diff --git a/patches/mfplat-streaming-support/0081-winegstreamer-Use-an-optional-h264parse-wg_transform.patch b/patches/mfplat-streaming-support/0081-winegstreamer-Use-an-optional-h264parse-wg_transform.patch deleted file mode 100644 index 09b589ff..00000000 --- a/patches/mfplat-streaming-support/0081-winegstreamer-Use-an-optional-h264parse-wg_transform.patch +++ /dev/null @@ -1,44 +0,0 @@ -From e4378c0f59983416570621596b875ca91048bb7c Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?R=C3=A9mi=20Bernon?= -Date: Fri, 21 Jan 2022 21:46:08 +0100 -Subject: [PATCH 81/88] winegstreamer: Use an optional h264parse wg_transform - element. - -Required for Mortal Kombat 11. - -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715 -Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183 -CW-Bug-Id: #16839 -CW-Bug-Id: #18678 -CW-Bug-Id: #19362 ---- - dlls/winegstreamer/wg_transform.c | 11 +++++++++++ - 1 file changed, 11 insertions(+) - -diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c -index df37b4e8543..e3b7d8ed056 100644 ---- a/dlls/winegstreamer/wg_transform.c -+++ b/dlls/winegstreamer/wg_transform.c -@@ -366,6 +366,17 @@ NTSTATUS wg_transform_create(void *args) - transform->container = gst_bin_new("wg_transform"); - assert(transform->container); - -+ switch (input_format.encoded_type) -+ { -+ case WG_ENCODED_TYPE_H264: -+ if ((element = create_element("h264parse", "base")) && -+ !transform_append_element(transform, element, &first, &last)) -+ goto failed; -+ break; -+ default: -+ break; -+ } -+ - if (!(element = try_create_transform(src_caps, raw_caps)) || - !transform_append_element(transform, element, &first, &last)) - goto failed; --- -2.34.1 -