[PATCH v4 7/8] winegstreamer: Support wg_transform output format change events.
Rémi Bernon
wine at gitlab.winehq.org
Wed May 25 05:08:55 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