Needed for Gungrave G.O.R.E. (besides some bits in raw AAC handling).
The game is fine with GetInputStatus always returning MFT_INPUT_STATUS_ACCEPT_DATA for both h264 and aac but I think it is better to be correct here.
From: Paul Gofman pgofman@codeweavers.com
--- dlls/mf/tests/transform.c | 35 +++++++++++++++++++++++++++++++ dlls/winegstreamer/h264_decoder.c | 11 ++++++++-- 2 files changed, 44 insertions(+), 2 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 3c068aae743..78332deeae7 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -3502,6 +3502,7 @@ static void test_h264_decoder(void) IMFMediaType *media_type; IMFTransform *transform; ULONG i, ret, ref; + DWORD flags; HRESULT hr;
hr = CoInitialize(NULL); @@ -3538,6 +3539,11 @@ static void test_h264_decoder(void) hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type); ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "GetOutputAvailableType returned %#lx\n", hr);
+ flags = 0xdeadbeef; + hr = IMFTransform_GetInputStatus(transform, 0, &flags); + ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Got %#lx\n", hr); + ok(flags == 0xdeadbeef, "Got flags %#lx.\n", flags); + /* setting output media type first doesn't work */ check_mft_set_output_type(transform, output_type_desc, MF_E_TRANSFORM_TYPE_NOT_SET); check_mft_get_output_current_type(transform, NULL); @@ -3610,6 +3616,12 @@ static void test_h264_decoder(void) ok(hr == E_INVALIDARG || hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#lx\n", hr); ok(output_status == 0, "got output[0].dwStatus %#lx\n", output_status);
+ if (0) + { + /* Crashes on Windows. */ + IMFTransform_GetInputStatus(transform, 0, NULL); + } + i = 0; input_sample = next_h264_sample(&h264_encoded_data, &h264_encoded_data_len); while (1) @@ -3626,12 +3638,18 @@ static void test_h264_decoder(void) ret = IMFSample_Release(output_sample); ok(ret == 0, "Release returned %lu\n", ret);
+ hr = IMFTransform_GetInputStatus(transform, 0, &flags); + ok(hr == S_OK, "Got %#lx\n", hr); + ok(flags == MFT_INPUT_STATUS_ACCEPT_DATA, "Got flags %#lx.\n", flags); hr = IMFTransform_ProcessInput(transform, 0, input_sample, 0); ok(hr == S_OK, "ProcessInput returned %#lx\n", hr); ret = IMFSample_Release(input_sample); ok(ret <= 1, "Release returned %lu\n", ret); input_sample = next_h264_sample(&h264_encoded_data, &h264_encoded_data_len);
+ hr = IMFTransform_GetInputStatus(transform, 0, &flags); + ok(hr == S_OK, "Got %#lx\n", hr); + ok(flags == MFT_INPUT_STATUS_ACCEPT_DATA, "Got flags %#lx.\n", flags); hr = IMFTransform_ProcessInput(transform, 0, input_sample, 0); ok(hr == S_OK, "ProcessInput returned %#lx\n", hr); ret = IMFSample_Release(input_sample); @@ -3754,6 +3772,23 @@ static void test_h264_decoder(void) ret = IMFSample_Release(output_sample); ok(ret == 0, "Release returned %lu\n", ret);
+ do + { + flags = 0; + hr = IMFTransform_GetInputStatus(transform, 0, &flags); + ok(hr == S_OK, "Got %#lx\n", hr); + ok(flags == MFT_INPUT_STATUS_ACCEPT_DATA, "Got flags %#lx.\n", flags); + hr = IMFTransform_ProcessInput(transform, 0, input_sample, 0); + ok(hr == S_OK || hr == MF_E_NOTACCEPTING, "Got %#lx\n", hr); + input_sample = next_h264_sample(&h264_encoded_data, &h264_encoded_data_len); + } while (hr == S_OK); + + ok(hr == MF_E_NOTACCEPTING, "Got %#lx\n", hr); + flags = 0; + hr = IMFTransform_GetInputStatus(transform, 0, &flags); + ok(hr == S_OK, "Got %#lx\n", hr); + ok(flags == MFT_INPUT_STATUS_ACCEPT_DATA, "Got flags %#lx.\n", flags); + ret = IMFTransform_Release(transform); ok(ret == 0, "Release returned %lu\n", ret); ret = IMFSample_Release(input_sample); diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c index ead00e20840..f904c3b9a41 100644 --- a/dlls/winegstreamer/h264_decoder.c +++ b/dlls/winegstreamer/h264_decoder.c @@ -548,8 +548,15 @@ static HRESULT WINAPI transform_GetOutputCurrentType(IMFTransform *iface, DWORD
static HRESULT WINAPI transform_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags) { - FIXME("iface %p, id %#lx, flags %p stub!\n", iface, id, flags); - return E_NOTIMPL; + struct h264_decoder *decoder = impl_from_IMFTransform(iface); + + TRACE("iface %p, id %#lx, flags %p.\n", iface, id, flags); + + if (!decoder->wg_transform) + return MF_E_TRANSFORM_TYPE_NOT_SET; + + *flags = MFT_INPUT_STATUS_ACCEPT_DATA; + return S_OK; }
static HRESULT WINAPI transform_GetOutputStatus(IMFTransform *iface, DWORD *flags)
From: Paul Gofman pgofman@codeweavers.com
--- dlls/mf/tests/transform.c | 23 +++++++++++++++++++++++ dlls/winegstreamer/aac_decoder.c | 16 ++++++++++++++-- dlls/winegstreamer/gst_private.h | 1 + dlls/winegstreamer/main.c | 11 +++++++++++ dlls/winegstreamer/unix_private.h | 1 + dlls/winegstreamer/unixlib.h | 7 +++++++ dlls/winegstreamer/wg_parser.c | 1 + dlls/winegstreamer/wg_transform.c | 17 +++++++++++++++++ 8 files changed, 75 insertions(+), 2 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 78332deeae7..45758242639 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -2370,6 +2370,7 @@ static void test_aac_decoder(void) IMFMediaType *media_type; IMFTransform *transform; const BYTE *aacenc_data; + DWORD flags; HRESULT hr;
hr = CoInitialize(NULL); @@ -2449,10 +2450,21 @@ static void test_aac_decoder(void) ok(aacenc_data_len == 24861, "got length %lu\n", aacenc_data_len);
input_sample = create_sample(aacenc_data + sizeof(DWORD), *(DWORD *)aacenc_data); + + flags = 0; + hr = IMFTransform_GetInputStatus(transform, 0, &flags); + ok(hr == S_OK, "Got %#lx\n", hr); + ok(flags == MFT_INPUT_STATUS_ACCEPT_DATA, "Got flags %#lx.\n", flags); hr = IMFTransform_ProcessInput(transform, 0, input_sample, 0); ok(hr == S_OK, "ProcessInput returned %#lx\n", hr); + hr = IMFTransform_GetInputStatus(transform, 0, &flags); + ok(hr == S_OK, "Got %#lx\n", hr); + ok(!flags, "Got flags %#lx.\n", flags); hr = IMFTransform_ProcessInput(transform, 0, input_sample, 0); ok(hr == MF_E_NOTACCEPTING, "ProcessInput returned %#lx\n", hr); + hr = IMFTransform_GetInputStatus(transform, 0, &flags); + ok(hr == S_OK, "Got %#lx\n", hr); + ok(!flags, "Got flags %#lx.\n", flags);
/* As output_info.dwFlags doesn't have MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES * IMFTransform_ProcessOutput needs a sample or returns MF_E_TRANSFORM_NEED_MORE_INPUT */ @@ -2460,11 +2472,17 @@ static void test_aac_decoder(void) hr = check_mft_process_output(transform, NULL, &output_status); ok(hr == E_INVALIDARG, "ProcessOutput returned %#lx\n", hr); ok(output_status == 0, "got output[0].dwStatus %#lx\n", output_status); + hr = IMFTransform_GetInputStatus(transform, 0, &flags); + ok(hr == S_OK, "Got %#lx\n", hr); + ok(!flags, "Got flags %#lx.\n", flags); hr = IMFTransform_ProcessInput(transform, 0, input_sample, 0); ok(hr == MF_E_NOTACCEPTING, "ProcessInput returned %#lx\n", hr);
hr = IMFTransform_ProcessMessage(transform, MFT_MESSAGE_COMMAND_DRAIN, 0); ok(hr == S_OK, "ProcessMessage returned %#lx\n", hr); + hr = IMFTransform_GetInputStatus(transform, 0, &flags); + ok(hr == S_OK, "Got %#lx\n", hr); + ok(!flags, "Got flags %#lx.\n", flags); hr = IMFTransform_ProcessInput(transform, 0, input_sample, 0); ok(hr == MF_E_NOTACCEPTING, "ProcessInput returned %#lx\n", hr);
@@ -2484,6 +2502,11 @@ static void test_aac_decoder(void) winetest_pop_context(); } ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#lx\n", hr); + + hr = IMFTransform_GetInputStatus(transform, 0, &flags); + ok(hr == S_OK, "Got %#lx\n", hr); + ok(flags == MFT_INPUT_STATUS_ACCEPT_DATA, "Got flags %#lx.\n", flags); + ok(output_status == MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE, "got output[0].dwStatus %#lx\n", output_status); ret = IMFSample_Release(output_sample); ok(ret == 0, "Release returned %lu\n", ret); diff --git a/dlls/winegstreamer/aac_decoder.c b/dlls/winegstreamer/aac_decoder.c index a2a6984dd18..8366ac7bb36 100644 --- a/dlls/winegstreamer/aac_decoder.c +++ b/dlls/winegstreamer/aac_decoder.c @@ -500,8 +500,20 @@ static HRESULT WINAPI transform_GetOutputCurrentType(IMFTransform *iface, DWORD
static HRESULT WINAPI transform_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags) { - FIXME("iface %p, id %#lx, flags %p stub!\n", iface, id, flags); - return E_NOTIMPL; + struct aac_decoder *decoder = impl_from_IMFTransform(iface); + bool accepts_input; + HRESULT hr; + + TRACE("iface %p, id %#lx, flags %p.\n", iface, id, flags); + + if (!decoder->wg_transform) + return MF_E_TRANSFORM_TYPE_NOT_SET; + + if (FAILED(hr = wg_transform_get_status(decoder->wg_transform, &accepts_input))) + return hr; + + *flags = accepts_input ? MFT_INPUT_STATUS_ACCEPT_DATA : 0; + return S_OK; }
static HRESULT WINAPI transform_GetOutputStatus(IMFTransform *iface, DWORD *flags) diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 3890db543ff..1e4aad32f44 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -104,6 +104,7 @@ 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); 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);
unsigned int wg_format_get_max_size(const struct wg_format *format);
diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c index 2675430019f..ceae11ae0d6 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -384,6 +384,17 @@ HRESULT wg_transform_read_data(struct wg_transform *transform, struct wg_sample return params.result; }
+bool wg_transform_get_status(struct wg_transform *transform, bool *accepts_input) +{ + struct wg_transform_get_status_params params = + { + .transform = transform, + .accepts_input = accepts_input, + }; + + return !WINE_UNIX_CALL(unix_wg_transform_get_status, ¶ms); +} + bool wg_transform_set_output_format(struct wg_transform *transform, struct wg_format *format) { struct wg_transform_set_output_format_params params = diff --git a/dlls/winegstreamer/unix_private.h b/dlls/winegstreamer/unix_private.h index 617204e97c7..ce67134af16 100644 --- a/dlls/winegstreamer/unix_private.h +++ b/dlls/winegstreamer/unix_private.h @@ -37,6 +37,7 @@ extern NTSTATUS wg_transform_destroy(void *args) DECLSPEC_HIDDEN; extern NTSTATUS wg_transform_set_output_format(void *args) DECLSPEC_HIDDEN; 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;
/* wg_allocator_release_sample can be used to release any sample that was requested. */ typedef struct wg_sample *(*wg_allocator_request_sample_cb)(gsize size, void *context); diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h index 5424633003e..f6b2fe8c1a6 100644 --- a/dlls/winegstreamer/unixlib.h +++ b/dlls/winegstreamer/unixlib.h @@ -310,6 +310,12 @@ struct wg_transform_set_output_format_params const struct wg_format *format; };
+struct wg_transform_get_status_params +{ + struct wg_transform *transform; + bool *accepts_input; +}; + enum unix_funcs { unix_wg_parser_create, @@ -343,6 +349,7 @@ enum unix_funcs
unix_wg_transform_push_data, unix_wg_transform_read_data, + unix_wg_transform_get_status, };
#endif /* __WINE_WINEGSTREAMER_UNIXLIB_H */ diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index f2c59488ef3..32ac4a2830d 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -1815,4 +1815,5 @@ const unixlib_entry_t __wine_unix_call_funcs[] =
X(wg_transform_push_data), X(wg_transform_read_data), + X(wg_transform_get_status), }; diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c index 302a64eb57b..1af885ff2b9 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -931,3 +931,20 @@ NTSTATUS wg_transform_read_data(void *args) wg_allocator_release_sample(transform->allocator, sample, discard_data); return STATUS_SUCCESS; } + +NTSTATUS wg_transform_get_status(void *args) +{ + struct wg_transform_get_status_params *params = args; + struct wg_transform *transform = params->transform; + bool *accepts_input = params->accepts_input; + guint length; + + if (accepts_input) + { + length = gst_atomic_queue_length(transform->input_queue); + fprintf(stderr, "qqqqq wg_transform_get_status length %d, max %d.\n", length, transform->input_max_length); + *accepts_input = length < transform->input_max_length; + } + + return STATUS_SUCCESS; +}
From: Paul Gofman pgofman@codeweavers.com
--- dlls/mf/tests/transform.c | 2 +- dlls/winegstreamer/h264_decoder.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 45758242639..a6f809e9947 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -3247,7 +3247,7 @@ static void test_h264_decoder(void) { ATTR_UINT32(MF_LOW_LATENCY, 0), ATTR_UINT32(MF_SA_D3D_AWARE, 1, .todo = TRUE), - ATTR_UINT32(MF_SA_D3D11_AWARE, 1, .todo = TRUE), + ATTR_UINT32(MF_SA_D3D11_AWARE, 1), ATTR_UINT32(MFT_DECODER_EXPOSE_OUTPUT_TYPES_IN_NATIVE_ORDER, 0, .todo = TRUE), /* more H264 decoder specific attributes from CODECAPI */ {0}, diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c index f904c3b9a41..439701098ad 100644 --- a/dlls/winegstreamer/h264_decoder.c +++ b/dlls/winegstreamer/h264_decoder.c @@ -725,6 +725,8 @@ HRESULT h264_decoder_create(REFIID riid, void **ret) goto failed; if (FAILED(hr = IMFAttributes_SetUINT32(decoder->attributes, &MF_LOW_LATENCY, 0))) goto failed; + if (FAILED(hr = IMFAttributes_SetUINT32(decoder->attributes, &MF_SA_D3D11_AWARE, TRUE))) + goto failed; if (FAILED(hr = MFCreateAttributes(&decoder->output_attributes, 0))) goto failed; if (FAILED(hr = wg_sample_queue_create(&decoder->wg_sample_queue)))
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=128964
Your paranoid android.
=== debian11 (32 bit report) ===
user32: msg.c:19187: Test failed: SendMessage from other thread 1: 1: the msg 0x0400 was expected, but got msg 0x0403 instead msg.c:19187: Test failed: SendMessage from other thread 1: 2: the msg sequence is not complete: expected 0000 - actual 0400