[PATCH v2 6/6] winegstreamer: Support dynamic wg_transform output format change.

Rémi Bernon wine at gitlab.winehq.org
Thu May 5 02:31:48 CDT 2022


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

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
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/mf/tests/mf.c                |  4 ----
 dlls/winegstreamer/h264_decoder.c |  8 ++++++++
 dlls/winegstreamer/unixlib.h      |  1 +
 dlls/winegstreamer/wg_transform.c | 13 +++++++++++++
 4 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index b6c37ea371f..df334dd6343 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -7139,20 +7139,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 58960cd632a..035fb72a660 100644
--- a/dlls/winegstreamer/h264_decoder.c
+++ b/dlls/winegstreamer/h264_decoder.c
@@ -50,6 +50,7 @@ struct h264_decoder
     IMFMediaType *input_type;
     IMFMediaType *output_type;
 
+    struct wg_format stream_format;
     struct wg_transform *wg_transform;
 };
 
@@ -561,11 +562,18 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags,
     if (FAILED(hr = mf_create_wg_sample(samples[0].pSample, &wg_sample)))
         return hr;
 
+    wg_sample->format = &decoder->stream_format;
     if (wg_sample->max_size < info.cbSize)
         hr = MF_E_BUFFERTOOSMALL;
     else
         hr = wg_transform_read_data(decoder->wg_transform, 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;
+    }
+
     mf_destroy_wg_sample(wg_sample);
     return hr;
 }
diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h
index b8dd2194bbe..0a0e5b592da 100644
--- a/dlls/winegstreamer/unixlib.h
+++ b/dlls/winegstreamer/unixlib.h
@@ -128,6 +128,7 @@ struct wg_sample
     UINT32 max_size;
     UINT32 size;
     BYTE *data;
+    struct wg_format *format;
 };
 
 struct wg_parser_buffer
diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c
index 7f17c0c1ad7..27e3ec219cf 100644
--- a/dlls/winegstreamer/wg_transform.c
+++ b/dlls/winegstreamer/wg_transform.c
@@ -469,8 +469,10 @@ NTSTATUS wg_transform_read_data(void *args)
     struct wg_transform *transform = params->transform;
     struct wg_sample *sample = params->sample;
     GstBufferList *input = transform->input;
+    struct wg_format format;
     GstFlowReturn ret;
     NTSTATUS status;
+    GstCaps *caps;
 
     if (!gst_buffer_list_length(transform->input))
         GST_DEBUG("Not input buffer queued");
@@ -493,6 +495,17 @@ NTSTATUS wg_transform_read_data(void *args)
         return STATUS_SUCCESS;
     }
 
+    if (sample->format && (caps = gst_sample_get_caps(transform->output_sample)))
+    {
+        wg_format_from_caps(&format, caps);
+        if (!wg_format_compare(&format, sample->format))
+        {
+            *sample->format = format;
+            params->result = MF_E_TRANSFORM_STREAM_CHANGE;
+            return STATUS_SUCCESS;
+        }
+    }
+
     if ((status = read_transform_output_data(gst_sample_get_buffer(transform->output_sample), sample)))
     {
         sample->size = 0;
-- 
GitLab

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



More information about the wine-devel mailing list