From: Rémi Bernon rbernon@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 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/winegstreamer/gst_private.h | 3 ++- dlls/winegstreamer/h264_decoder.c | 9 ++++++++- dlls/winegstreamer/main.c | 6 ++++-- dlls/winegstreamer/quartz_transform.c | 2 +- dlls/winegstreamer/unixlib.h | 1 + dlls/winegstreamer/wg_transform.c | 14 ++++++++++++++ dlls/winegstreamer/wma_decoder.c | 2 +- 7 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 2a4b16079c1..159143d7e54 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -97,7 +97,8 @@ struct wg_transform *wg_transform_create(const struct wg_format *input_format, const struct wg_format *output_format); void wg_transform_destroy(struct wg_transform *transform); HRESULT wg_transform_push_data(struct wg_transform *transform, struct wg_sample *sample); -HRESULT wg_transform_read_data(struct wg_transform *transform, struct wg_sample *sample); +HRESULT wg_transform_read_data(struct wg_transform *transform, struct wg_sample *sample, + struct wg_format *format);
unsigned int wg_format_get_max_size(const struct wg_format *format);
diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c index 58960cd632a..68f4ba7562d 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 format; struct wg_transform *wg_transform; };
@@ -564,7 +565,13 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags, if (wg_sample->max_size < info.cbSize) hr = MF_E_BUFFERTOOSMALL; else - hr = wg_transform_read_data(decoder->wg_transform, wg_sample); + hr = wg_transform_read_data(decoder->wg_transform, wg_sample, &decoder->format); + + 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/main.c b/dlls/winegstreamer/main.c index c3adbb82d61..5075b3118cd 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -329,16 +329,18 @@ HRESULT wg_transform_push_data(struct wg_transform *transform, struct wg_sample return params.result; }
-HRESULT wg_transform_read_data(struct wg_transform *transform, struct wg_sample *sample) +HRESULT wg_transform_read_data(struct wg_transform *transform, struct wg_sample *sample, + struct wg_format *format) { struct wg_transform_read_data_params params = { .transform = transform, .sample = sample, + .format = format, }; NTSTATUS status;
- TRACE("transform %p, sample %p.\n", transform, sample); + TRACE("transform %p, sample %p, format %p.\n", transform, sample, format);
if ((status = __wine_unix_call(unix_handle, unix_wg_transform_read_data, ¶ms))) return HRESULT_FROM_NT(status); diff --git a/dlls/winegstreamer/quartz_transform.c b/dlls/winegstreamer/quartz_transform.c index 447f331d474..3b43f182ecb 100644 --- a/dlls/winegstreamer/quartz_transform.c +++ b/dlls/winegstreamer/quartz_transform.c @@ -342,7 +342,7 @@ static HRESULT WINAPI transform_sink_receive(struct strmbase_sink *pin, IMediaSa return hr; }
- hr = wg_transform_read_data(filter->transform, &output_wg_sample); + hr = wg_transform_read_data(filter->transform, &output_wg_sample, NULL); if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) { IMediaSample_Release(output_sample); diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h index 5911278530d..e8cdfaf7217 100644 --- a/dlls/winegstreamer/unixlib.h +++ b/dlls/winegstreamer/unixlib.h @@ -257,6 +257,7 @@ struct wg_transform_read_data_params { struct wg_transform *transform; struct wg_sample *sample; + struct wg_format *format; HRESULT result; };
diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c index 87baa80e840..66f8da0a940 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -483,8 +483,10 @@ NTSTATUS wg_transform_read_data(void *args) struct wg_sample *sample = params->sample; GstBufferList *input = transform->input; GstBuffer *output_buffer; + struct wg_format format; GstFlowReturn ret; NTSTATUS status; + GstCaps *caps;
if (!gst_buffer_list_length(transform->input)) GST_DEBUG("Not input buffer queued"); @@ -508,6 +510,18 @@ NTSTATUS wg_transform_read_data(void *args) } output_buffer = gst_sample_get_buffer(transform->output_sample);
+ if (params->format && (caps = gst_sample_get_caps(transform->output_sample))) + { + wg_format_from_caps(&format, caps); + if (!wg_format_compare(&format, params->format)) + { + *params->format = format; + 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))) { sample->size = 0; diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c index 71369add244..2bad84df0de 100644 --- a/dlls/winegstreamer/wma_decoder.c +++ b/dlls/winegstreamer/wma_decoder.c @@ -580,7 +580,7 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags, wg_sample->size = 0; if (wg_sample->max_size < info.cbSize) hr = MF_E_BUFFERTOOSMALL; - else if (SUCCEEDED(hr = wg_transform_read_data(decoder->wg_transform, wg_sample))) + else if (SUCCEEDED(hr = wg_transform_read_data(decoder->wg_transform, wg_sample, NULL))) { if (wg_sample->flags & WG_SAMPLE_FLAG_INCOMPLETE) samples[0].dwStatus |= MFT_OUTPUT_DATA_BUFFER_INCOMPLETE;