[PATCH v2 5/6] winegstreamer: Support wg_transform output format change events.
Rémi Bernon
wine at gitlab.winehq.org
Fri May 13 04:48:33 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.
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 | 23 ++++++++++++++++++++++-
dlls/winegstreamer/wma_decoder.c | 8 ++++++++
5 files changed, 39 insertions(+), 5 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index 7170bad85a0..291c9d0a175 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -7147,20 +7147,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 912a5bdf0b1..ea80956b038 100644
--- a/dlls/winegstreamer/h264_decoder.c
+++ b/dlls/winegstreamer/h264_decoder.c
@@ -569,6 +569,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 447f331d474..44f4cd44ff4 100644
--- a/dlls/winegstreamer/quartz_transform.c
+++ b/dlls/winegstreamer/quartz_transform.c
@@ -350,6 +350,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 b6cc51aecb7..9edcd72754f 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;
@@ -504,6 +517,14 @@ 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 71369add244..57931a700eb 100644
--- a/dlls/winegstreamer/wma_decoder.c
+++ b/dlls/winegstreamer/wma_decoder.c
@@ -587,6 +587,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