[PATCH v5 7/8] winegstreamer: Support wg_transform output format change events.

Rémi Bernon wine at gitlab.winehq.org
Wed May 25 16:51:15 CDT 2022


From: Rémi Bernon <rbernon at codeweavers.com>

Adding an info structure to the sample when the caps have changed,
removing if once it has been reported to the caller, and optionally
returning the new stream format.

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
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/mf/tests/mf.c                    |  4 ----
 dlls/winegstreamer/h264_decoder.c     |  7 +++++++
 dlls/winegstreamer/quartz_transform.c |  2 ++
 dlls/winegstreamer/wg_transform.c     | 24 +++++++++++++++++++++++-
 dlls/winegstreamer/wma_decoder.c      |  8 ++++++++
 5 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index 9de7308f9ff..419faa61e2b 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -7187,20 +7187,16 @@ static void test_h264_decoder(void)
     ok(i == 2, "got %lu iterations\n", i);
     todo_wine
     ok(h264_encoded_data_len == 1180, "got h264_encoded_data_len %lu\n", h264_encoded_data_len);
-    todo_wine
     ok(hr == MF_E_TRANSFORM_STREAM_CHANGE, "ProcessOutput returned %#lx\n", hr);
     ok(output.dwStreamID == 0, "got dwStreamID %lu\n", output.dwStreamID);
     ok(!!output.pSample, "got pSample %p\n", output.pSample);
-    todo_wine
     ok(output.dwStatus == MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE,
             "got dwStatus %#lx\n", output.dwStatus);
     ok(!output.pEvents, "got pEvents %p\n", output.pEvents);
-    todo_wine
     ok(status == MFT_PROCESS_OUTPUT_STATUS_NEW_STREAMS,
             "got status %#lx\n", status);
     hr = IMFSample_GetTotalLength(output.pSample, &length);
     ok(hr == S_OK, "GetTotalLength returned %#lx\n", hr);
-    todo_wine
     ok(length == 0, "got length %lu\n", length);
     ret = IMFSample_Release(output.pSample);
     ok(ret == 0, "Release returned %lu\n", ret);
diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c
index 66d53a3a5ce..b3452269f04 100644
--- a/dlls/winegstreamer/h264_decoder.c
+++ b/dlls/winegstreamer/h264_decoder.c
@@ -571,6 +571,13 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags,
 
     hr = wg_transform_read_data(decoder->wg_transform, wg_sample);
     mf_destroy_wg_sample(wg_sample);
+
+    if (hr == MF_E_TRANSFORM_STREAM_CHANGE)
+    {
+        samples[0].dwStatus |= MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE;
+        *status |= MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE;
+    }
+
     return hr;
 }
 
diff --git a/dlls/winegstreamer/quartz_transform.c b/dlls/winegstreamer/quartz_transform.c
index 7986997abef..e093e2c201e 100644
--- a/dlls/winegstreamer/quartz_transform.c
+++ b/dlls/winegstreamer/quartz_transform.c
@@ -358,6 +358,8 @@ static HRESULT WINAPI transform_sink_receive(struct strmbase_sink *pin, IMediaSa
         }
         if (FAILED(hr))
         {
+            if (hr == MF_E_TRANSFORM_STREAM_CHANGE)
+                FIXME("Unexpected stream format change!\n");
             IMediaSample_Release(output_sample);
             return hr;
         }
diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c
index f8211001be9..06b26a04310 100644
--- a/dlls/winegstreamer/wg_transform.c
+++ b/dlls/winegstreamer/wg_transform.c
@@ -52,17 +52,27 @@ struct wg_transform
     guint input_max_length;
     GstAtomicQueue *output_queue;
     GstSample *output_sample;
+    bool output_caps_changed;
     GstCaps *output_caps;
 };
 
 static GstFlowReturn transform_sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *buffer)
 {
     struct wg_transform *transform = gst_pad_get_element_private(pad);
+    GstStructure *info = NULL;
     GstSample *sample;
 
     GST_LOG("transform %p, buffer %p.", transform, buffer);
 
-    if (!(sample = gst_sample_new(buffer, transform->output_caps, NULL, NULL)))
+    if (transform->output_caps_changed && !(info = gst_structure_new_empty("format-changed")))
+    {
+        GST_ERROR("Failed to allocate transform %p output sample info.", transform);
+        gst_buffer_unref(buffer);
+        return GST_FLOW_ERROR;
+    }
+    transform->output_caps_changed = false;
+
+    if (!(sample = gst_sample_new(buffer, transform->output_caps, NULL, info)))
     {
         GST_ERROR("Failed to allocate transform %p output sample.", transform);
         gst_buffer_unref(buffer);
@@ -88,6 +98,9 @@ static gboolean transform_sink_event_cb(GstPad *pad, GstObject *parent, GstEvent
 
             gst_event_parse_caps(event, &caps);
 
+            transform->output_caps_changed = transform->output_caps_changed
+                    || !gst_caps_is_always_compatible(transform->output_caps, caps);
+
             gst_caps_unref(transform->output_caps);
             transform->output_caps = gst_caps_ref(caps);
             break;
@@ -505,6 +518,15 @@ NTSTATUS wg_transform_read_data(void *args)
 
     output_buffer = gst_sample_get_buffer(transform->output_sample);
 
+    if (gst_sample_get_info(transform->output_sample))
+    {
+        gst_sample_set_info(transform->output_sample, NULL);
+
+        params->result = MF_E_TRANSFORM_STREAM_CHANGE;
+        GST_INFO("Format changed detected, returning no output");
+        return STATUS_SUCCESS;
+    }
+
     if ((status = read_transform_output_data(output_buffer, sample)))
         return status;
 
diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c
index 70563649c9c..ca53816f134 100644
--- a/dlls/winegstreamer/wma_decoder.c
+++ b/dlls/winegstreamer/wma_decoder.c
@@ -593,6 +593,14 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags,
     }
 
     mf_destroy_wg_sample(wg_sample);
+
+    if (hr == MF_E_TRANSFORM_STREAM_CHANGE)
+    {
+        FIXME("Unexpected stream format change!\n");
+        samples[0].dwStatus |= MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE;
+        *status |= MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE;
+    }
+
     return hr;
 }
 
-- 
GitLab


https://gitlab.winehq.org/wine/wine/-/merge_requests/61



More information about the wine-devel mailing list