Rémi Bernon : winegstreamer: Support wg_transform output format change events.

Alexandre Julliard julliard at winehq.org
Wed May 25 16:51:48 CDT 2022


Module: wine
Branch: master
Commit: 8abbc0096da3b6e836d9b7559eb31a73f113bc2f
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=8abbc0096da3b6e836d9b7559eb31a73f113bc2f

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Fri May 13 00:17:28 2022 +0200

winegstreamer: Support wg_transform output format change events.

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;
 }
 




More information about the wine-cvs mailing list