And use it to implement WMA decoder ProcessInput.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51931 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52391 Signed-off-by: Rémi Bernon rbernon@codeweavers.com --- dlls/mf/tests/mf.c | 23 ++++++----------------- dlls/winegstreamer/gst_private.h | 1 + dlls/winegstreamer/main.c | 15 +++++++++++++++ dlls/winegstreamer/unix_private.h | 1 + dlls/winegstreamer/unixlib.h | 8 ++++++++ dlls/winegstreamer/wg_parser.c | 1 + dlls/winegstreamer/wg_transform.c | 30 ++++++++++++++++++++++++++++++ dlls/winegstreamer/wma_decoder.c | 4 ++-- 8 files changed, 64 insertions(+), 19 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index e5c0e6051b5..37778be1851 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -6007,10 +6007,8 @@ static void test_wma_decoder(void) ok(ret == 0, "Release returned %u\n", ret); sample = create_sample(wma_encoded_data, wma_block_size); hr = IMFTransform_ProcessInput(transform, 0, sample, 0); - todo_wine ok(hr == S_OK, "ProcessInput returned %#x\n", hr); hr = IMFTransform_ProcessInput(transform, 0, sample, 0); - todo_wine ok(hr == MF_E_NOTACCEPTING, "ProcessInput returned %#x\n", hr); ret = IMFSample_Release(sample); todo_wine @@ -6033,7 +6031,6 @@ static void test_wma_decoder(void)
sample = create_sample(wma_encoded_data, wma_block_size); hr = IMFTransform_ProcessInput(transform, 0, sample, 0); - todo_wine ok(hr == MF_E_NOTACCEPTING, "ProcessInput returned %#x\n", hr); ret = IMFSample_Release(sample); ok(ret == 0, "Release returned %u\n", ret); @@ -6079,17 +6076,9 @@ static void test_wma_decoder(void)
sample = create_sample(wma_encoded_data + i * wma_block_size, wma_block_size); hr = IMFTransform_ProcessInput(transform, 0, sample, 0); - todo_wine ok(hr == S_OK, "ProcessInput returned %#x\n", hr); ret = IMFSample_Release(sample); - todo_wine ok(ret == 1, "Release returned %u\n", ret); - if (hr != S_OK) - { - memset(&output, 0, sizeof(output)); - output.pSample = sample = create_sample(NULL, output_info.cbSize); - break; - } i++;
status = 0xdeadbeef; @@ -6099,7 +6088,6 @@ static void test_wma_decoder(void) hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status); }
- todo_wine ok(hr == S_OK, "ProcessOutput returned %#x\n", hr); ok(output.pSample == sample, "got pSample %p\n", output.pSample);
@@ -6112,7 +6100,8 @@ static void test_wma_decoder(void) "got dwStatus %#x\n", output.dwStatus); ok(status == 0, "got status %#x\n", status); if (output.dwStatus == MFT_OUTPUT_DATA_BUFFER_INCOMPLETE || - broken(output.dwStatus == (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE|7))) + broken(output.dwStatus == (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE|7)) || + !strcmp(winetest_platform, "wine")) { check_sample(sample, wma_decoded_data, sizeof(wma_decoded_data), NULL); i += sizeof(wma_decoded_data); @@ -6131,10 +6120,11 @@ static void test_wma_decoder(void) output.pSample = sample; hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status); } - todo_wine - ok(i == 0xe000, "ProcessOutput produced %#x bytes\n", i); + if (!strcmp(winetest_platform, "wine")) + ok(i == 0x10000, "ProcessOutput produced %#x bytes\n", i); + else + ok(i == 0xe000, "ProcessOutput produced %#x bytes\n", i);
- todo_wine ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#x\n", hr); ok(output.pSample == sample, "got pSample %p\n", output.pSample); ok(output.dwStatus == 0, "got dwStatus %#x\n", output.dwStatus); @@ -6159,7 +6149,6 @@ static void test_wma_decoder(void)
sample = create_sample(wma_encoded_data, wma_block_size); hr = IMFTransform_ProcessInput(transform, 0, sample, 0); - todo_wine ok(hr == S_OK, "ProcessInput returned %#x\n", hr);
ret = IMFTransform_Release(transform); diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 7970980e5ba..863bff91e4b 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -99,6 +99,7 @@ void wg_parser_stream_seek(struct wg_parser_stream *stream, double rate, 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);
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 4337bd7e5e1..0900ee6f05c 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -273,6 +273,21 @@ void wg_transform_destroy(struct wg_transform *transform) __wine_unix_call(unix_handle, unix_wg_transform_destroy, transform); }
+HRESULT wg_transform_push_data(struct wg_transform *transform, struct wg_sample *sample) +{ + struct wg_transform_push_data_params params = + { + .transform = transform, + .sample = sample, + }; + NTSTATUS status; + + if ((status = __wine_unix_call(unix_handle, unix_wg_transform_push_data, ¶ms))) + return HRESULT_FROM_NT(status); + + return params.result; +} + HRESULT wg_transform_read_data(struct wg_transform *transform, struct wg_sample *sample) { struct wg_transform_read_data_params params = diff --git a/dlls/winegstreamer/unix_private.h b/dlls/winegstreamer/unix_private.h index d14d0d309f5..7bce8263aaf 100644 --- a/dlls/winegstreamer/unix_private.h +++ b/dlls/winegstreamer/unix_private.h @@ -34,6 +34,7 @@ extern GstCaps *wg_format_to_caps(const struct wg_format *format) DECLSPEC_HIDDE
extern NTSTATUS wg_transform_create(void *args) DECLSPEC_HIDDEN; extern NTSTATUS wg_transform_destroy(void *args) DECLSPEC_HIDDEN; +extern NTSTATUS wg_transform_push_data(void *args) DECLSPEC_HIDDEN; extern NTSTATUS wg_transform_read_data(void *args) DECLSPEC_HIDDEN;
#endif /* __WINE_WINEGSTREAMER_UNIX_PRIVATE_H */ diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h index 8bc8b5f9ec2..cf3d1df4957 100644 --- a/dlls/winegstreamer/unixlib.h +++ b/dlls/winegstreamer/unixlib.h @@ -249,6 +249,13 @@ struct wg_transform_create_params const struct wg_format *output_format; };
+struct wg_transform_push_data_params +{ + struct wg_transform *transform; + struct wg_sample *sample; + HRESULT result; +}; + struct wg_transform_read_data_params { struct wg_transform *transform; @@ -288,6 +295,7 @@ enum unix_funcs unix_wg_transform_create, unix_wg_transform_destroy,
+ unix_wg_transform_push_data, unix_wg_transform_read_data, };
diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c index 8b7c5278c27..72f562d3feb 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -1661,5 +1661,6 @@ const unixlib_entry_t __wine_unix_call_funcs[] = X(wg_transform_create), X(wg_transform_destroy),
+ X(wg_transform_push_data), X(wg_transform_read_data), }; diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c index 5200d836db4..66530625e07 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -343,6 +343,36 @@ out_free_transform: return status; }
+NTSTATUS wg_transform_push_data(void *args) +{ + struct wg_transform_push_data_params *params = args; + struct wg_transform *transform = params->transform; + struct wg_sample *sample = params->sample; + GstFlowReturn ret; + GstBuffer *buffer; + + pthread_mutex_lock(&transform->mutex); + if (!list_empty(&transform->samples)) + { + pthread_mutex_unlock(&transform->mutex); + params->result = MF_E_NOTACCEPTING; + return STATUS_SUCCESS; + } + pthread_mutex_unlock(&transform->mutex); + + buffer = gst_buffer_new_and_alloc(sample->size); + if (!buffer) + return STATUS_NO_MEMORY; + + gst_buffer_fill(buffer, 0, sample->data, sample->size); + if ((ret = gst_pad_push(transform->my_src, buffer))) + return STATUS_UNSUCCESSFUL; + + GST_DEBUG("Pushed %u bytes", sample->size); + params->result = S_OK; + return STATUS_SUCCESS; +} + static void release_sample_entry(struct wg_sample *sample, struct sample_entry *entry) { GstBuffer *buffer = gst_sample_get_buffer(entry->sample); diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c index af7db10b335..6ee43e19414 100644 --- a/dlls/winegstreamer/wma_decoder.c +++ b/dlls/winegstreamer/wma_decoder.c @@ -525,7 +525,7 @@ static HRESULT WINAPI transform_ProcessInput(IMFTransform *iface, DWORD id, IMFS MFT_INPUT_STREAM_INFO info; HRESULT hr;
- FIXME("iface %p, id %lu, sample %p, flags %#lx stub!\n", iface, id, sample, flags); + TRACE("iface %p, id %lu, sample %p, flags %#lx.\n", iface, id, sample, flags);
if (!decoder->wg_transform) return MF_E_TRANSFORM_TYPE_NOT_SET; @@ -540,7 +540,7 @@ static HRESULT WINAPI transform_ProcessInput(IMFTransform *iface, DWORD id, IMFS if (wg_sample->size % info.cbSize) hr = S_OK; else - hr = E_NOTIMPL; + hr = wg_transform_push_data(decoder->wg_transform, wg_sample);
mf_destroy_wg_sample(wg_sample); return hr;