From: Paul Gofman pgofman@codeweavers.com
--- dlls/mf/tests/transform.c | 28 ++++++++++++++++++++++++++++ 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 | 16 ++++++++++++++++ 8 files changed, 79 insertions(+), 2 deletions(-)
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 476bf225b33..143b5ed2b05 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,23 @@ 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); + flags = 0xdeadbeef; + 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); + flags = 0xdeadbeef; + 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 +2474,19 @@ 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); + flags = 0xdeadbeef; + 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); + flags = 0xdeadbeef; + 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 +2506,12 @@ static void test_aac_decoder(void) winetest_pop_context(); } ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#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); + 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..596414a72cd 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -931,3 +931,19 @@ 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); + *accepts_input = length < transform->input_max_length; + } + + return STATUS_SUCCESS; +}