[PATCH v2 8/8] winegstreamer: Introduce new wg_transform_push_data entry point.

Rémi Bernon rbernon at codeweavers.com
Wed Feb 23 08:46:39 CST 2022


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 at 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, &params)))
+        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;
-- 
2.34.1




More information about the wine-devel mailing list