From 4f4ee0e16b343c2c6f935c465c59dc3c705ebd65 Mon Sep 17 00:00:00 2001 From: Paul Gofman Date: Thu, 25 May 2023 15:07:20 +0200 Subject: [PATCH] winegstreamer: Implement MFT_MESSAGE_COMMAND_FLUSH for the H264 decoder. --- dlls/mf/tests/transform.c | 9 --------- dlls/winegstreamer/gst_private.h | 1 + dlls/winegstreamer/h264_decoder.c | 3 +++ dlls/winegstreamer/main.c | 15 +++++++++++++++ dlls/winegstreamer/unix_private.h | 1 + dlls/winegstreamer/unixlib.h | 1 + dlls/winegstreamer/wg_parser.c | 1 + dlls/winegstreamer/wg_transform.c | 24 ++++++++++++++++++++++++ 8 files changed, 46 insertions(+), 9 deletions(-) diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 27dd4ad17c2..55001d97025 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -4026,7 +4026,6 @@ static void test_h264_decoder_concat_streams(void) { {.length = 0x3600}, {.length = 0x4980}, - {.length = 0, .todo_length = TRUE}, }; const struct attribute_desc output_sample_attributes[] = { @@ -4057,13 +4056,6 @@ static void test_h264_decoder_concat_streams(void) .buffer_count = 1, .buffers = output_buffer_desc + 1, .repeat_count = 6, .todo_time = TRUE, }, - { - /* Wine outputs spurious buffers */ - .attributes = output_sample_attributes + 0, - .sample_time = 0, .sample_duration = 400000, - .buffer_count = 1, .buffers = output_buffer_desc + 2, .repeat_count = 22, - .todo_time = TRUE, .todo_length = TRUE, - }, {0}, }; const WCHAR *filenames[] = @@ -4212,7 +4204,6 @@ static void test_h264_decoder_concat_streams(void) hr = IMFCollection_GetElementCount(output_samples, &output_count); ok(hr == S_OK, "GetElementCount returned %#lx\n", hr); - todo_wine ok(output_count == 96, "GetElementCount returned %#lx\n", output_count); ret = check_mf_sample_collection(output_samples, output_sample_desc, NULL); diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 9a559f58507..af4590af8bb 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -107,6 +107,7 @@ void wg_transform_destroy(struct wg_transform *transform); bool wg_transform_set_output_format(struct wg_transform *transform, struct wg_format *format); bool wg_transform_get_status(struct wg_transform *transform, bool *accepts_input); HRESULT wg_transform_drain(struct wg_transform *transform); +HRESULT wg_transform_flush(struct wg_transform *transform); 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 96888e49178..f8d4ea10d5e 100644 --- a/dlls/winegstreamer/h264_decoder.c +++ b/dlls/winegstreamer/h264_decoder.c @@ -630,6 +630,9 @@ static HRESULT WINAPI transform_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_ case MFT_MESSAGE_COMMAND_DRAIN: return wg_transform_drain(decoder->wg_transform); + case MFT_MESSAGE_COMMAND_FLUSH: + return wg_transform_flush(decoder->wg_transform); + default: FIXME("Ignoring message %#x.\n", message); return S_OK; diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c index 955644b6a60..bd4f7108387 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -441,6 +441,21 @@ HRESULT wg_transform_drain(struct wg_transform *transform) return S_OK; } +HRESULT wg_transform_flush(struct wg_transform *transform) +{ + NTSTATUS status; + + TRACE("transform %p.\n", transform); + + if ((status = WINE_UNIX_CALL(unix_wg_transform_flush, transform))) + { + WARN("wg_transform_flush returned status %#lx\n", status); + return HRESULT_FROM_NT(status); + } + + return S_OK; +} + #define ALIGN(n, alignment) (((n) + (alignment) - 1) & ~((alignment) - 1)) unsigned int wg_format_get_stride(const struct wg_format *format) diff --git a/dlls/winegstreamer/unix_private.h b/dlls/winegstreamer/unix_private.h index dcc89298748..808b59dba57 100644 --- a/dlls/winegstreamer/unix_private.h +++ b/dlls/winegstreamer/unix_private.h @@ -54,6 +54,7 @@ extern NTSTATUS wg_transform_push_data(void *args) DECLSPEC_HIDDEN; extern NTSTATUS wg_transform_read_data(void *args) DECLSPEC_HIDDEN; extern NTSTATUS wg_transform_get_status(void *args) DECLSPEC_HIDDEN; extern NTSTATUS wg_transform_drain(void *args) DECLSPEC_HIDDEN; +extern NTSTATUS wg_transform_flush(void *args) DECLSPEC_HIDDEN; /* wg_allocator.c */ diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h index c712be0ed13..e03085cd4f7 100644 --- a/dlls/winegstreamer/unixlib.h +++ b/dlls/winegstreamer/unixlib.h @@ -377,6 +377,7 @@ enum unix_funcs unix_wg_transform_read_data, unix_wg_transform_get_status, unix_wg_transform_drain, + unix_wg_transform_flush, }; #endif /* __WINE_WINEGSTREAMER_UNIXLIB_H */ diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index c55685931ae..f043c4e18b4 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -1940,4 +1940,5 @@ const unixlib_entry_t __wine_unix_call_funcs[] = X(wg_transform_read_data), X(wg_transform_get_status), X(wg_transform_drain), + X(wg_transform_flush), }; diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c index 1f3d94d297b..054e574770c 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -904,3 +904,27 @@ error: GST_ERROR("Failed to drain transform %p.", transform); return STATUS_UNSUCCESSFUL; } + +NTSTATUS wg_transform_flush(void *args) +{ + struct wg_transform *transform = args; + GstBuffer *input_buffer; + GstSample *sample; + NTSTATUS status; + + GST_LOG("transform %p", transform); + + while ((input_buffer = gst_atomic_queue_pop(transform->input_queue))) + gst_buffer_unref(input_buffer); + + if ((status = wg_transform_drain(transform))) + return status; + + while ((sample = gst_atomic_queue_pop(transform->output_queue))) + gst_sample_unref(sample); + if ((sample = transform->output_sample)) + gst_sample_unref(sample); + transform->output_sample = NULL; + + return STATUS_SUCCESS; +} -- 2.11.4.GIT