[PATCH 1/3] winegstreamer: Implement WMA decoder Process(Input|Output) error checks.

Rémi Bernon rbernon at codeweavers.com
Mon Feb 28 10:27:08 CST 2022


Checking that WMA decoder ignores any incorrectly sized input sample.

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>
---

I believe this approach works best and doesn't suffer from any of the
potential troubles the queue would introduce. It should also be fully
synchronous in the general case, although I kept the mutex to be safe.

For now, one input buffer can be queued at a time, which is how the WMA
decoder transform works, and the output buffers are appended to each
other, although they are normally also produced one at a time.

Later, and to satisfy the requirements of the H264 transform and the
expectations of CoD: BO3, I will change the input to a GstBufferList
with a length limit.

Even for the zero-copy optimization, I was able to validate that it's
still possible, and even simpler to implement as we now do all the
processing in ProcessOutput.

We can then later consider adding some asynchronicity using queues, but
I'm not sure it is going to be useful, and may even cause more problems
than it's worth.

 dlls/mf/tests/mf.c               | 23 +++++++++++++---------
 dlls/winegstreamer/wma_decoder.c | 33 ++++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 9 deletions(-)

diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index e61442bb512..0ab46445d9a 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -6031,6 +6031,7 @@ static void test_wma_decoder(void)
     MFT_REGISTER_TYPE_INFO input_type = {MFMediaType_Audio, MFAudioFormat_WMAudioV8};
     MFT_REGISTER_TYPE_INFO output_type = {MFMediaType_Audio, MFAudioFormat_Float};
     MFT_OUTPUT_STREAM_INFO output_info;
+    MFT_OUTPUT_DATA_BUFFER outputs[2];
     MFT_INPUT_STREAM_INFO input_info;
     MFT_OUTPUT_DATA_BUFFER output;
     const BYTE *wma_encoded_data;
@@ -6208,7 +6209,7 @@ static void test_wma_decoder(void)
     ok(hr == S_OK, "ProcessInput returned %#x\n", hr);
     ret = IMFSample_Release(sample);
     ok(ret == 0, "Release returned %u\n", ret);
-    sample = create_sample(wma_encoded_data + wma_block_size, wma_block_size - wma_block_size / 2);
+    sample = create_sample(wma_encoded_data, wma_block_size + 1);
     hr = IMFTransform_ProcessInput(transform, 0, sample, 0);
     todo_wine
     ok(hr == S_OK, "ProcessInput returned %#x\n", hr);
@@ -6231,16 +6232,13 @@ static void test_wma_decoder(void)
     status = 0xdeadbeef;
     memset(&output, 0, sizeof(output));
     hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status);
-    todo_wine
     ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#x\n", hr);
     ok(output.dwStreamID == 0, "got dwStreamID %u\n", output.dwStreamID);
     ok(!output.pSample, "got pSample %p\n", output.pSample);
-    todo_wine
     ok(output.dwStatus == MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE ||
             broken(output.dwStatus == (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE|MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE)) /* Win7 */,
             "got dwStatus %#x\n", output.dwStatus);
     ok(!output.pEvents, "got pEvents %p\n", output.pEvents);
-    todo_wine
     ok(status == 0, "got status %#x\n", status);
 
     sample = create_sample(wma_encoded_data, wma_block_size);
@@ -6253,16 +6251,25 @@ static void test_wma_decoder(void)
     status = 0xdeadbeef;
     memset(&output, 0, sizeof(output));
     hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status);
-    todo_wine
     ok(hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#x\n", hr);
     ok(!output.pSample, "got pSample %p\n", output.pSample);
-    todo_wine
     ok(output.dwStatus == MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE ||
             broken(output.dwStatus == (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE|MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE)) /* Win7 */,
             "got dwStatus %#x\n", output.dwStatus);
-    todo_wine
     ok(status == 0, "got status %#x\n", status);
 
+    status = 0xdeadbeef;
+    memset(&output, 0, sizeof(output));
+    output_info.cbSize = sizeof(wma_decoded_data);
+    sample = create_sample(NULL, output_info.cbSize);
+    outputs[0].pSample = sample;
+    sample = create_sample(NULL, output_info.cbSize);
+    outputs[1].pSample = sample;
+    hr = IMFTransform_ProcessOutput(transform, 0, 2, outputs, &status);
+    ok(hr == E_INVALIDARG, "ProcessOutput returned %#x\n", hr);
+    IMFSample_Release(outputs[0].pSample);
+    IMFSample_Release(outputs[1].pSample);
+
     i = 1;
     status = 0xdeadbeef;
     output_info.cbSize = sizeof(wma_decoded_data);
@@ -6333,7 +6340,6 @@ static void test_wma_decoder(void)
     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);
-    todo_wine
     ok(status == 0, "got status %#x\n", status);
     ret = IMFSample_Release(sample);
     ok(ret == 0, "Release returned %u\n", ret);
@@ -6349,7 +6355,6 @@ static void test_wma_decoder(void)
     ok(output.dwStatus == 0 ||
             broken(output.dwStatus == (MFT_OUTPUT_DATA_BUFFER_INCOMPLETE|7)) /* Win7 */,
             "got dwStatus %#x\n", output.dwStatus);
-    todo_wine
     ok(status == 0, "got status %#x\n", status);
     check_sample(sample, NULL, 0, NULL);
     ret = IMFSample_Release(sample);
diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c
index 6c198706944..a35da1cdc70 100644
--- a/dlls/winegstreamer/wma_decoder.c
+++ b/dlls/winegstreamer/wma_decoder.c
@@ -520,14 +520,47 @@ static HRESULT WINAPI transform_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_
 
 static HRESULT WINAPI transform_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags)
 {
+    struct wma_decoder *decoder = impl_from_IMFTransform(iface);
+    MFT_INPUT_STREAM_INFO info;
+    HRESULT hr;
+
     FIXME("iface %p, id %lu, sample %p, flags %#lx stub!\n", iface, id, sample, flags);
+
+    if (!decoder->wg_transform)
+        return MF_E_TRANSFORM_TYPE_NOT_SET;
+
+    if (FAILED(hr = IMFTransform_GetInputStreamInfo(iface, 0, &info)))
+        return hr;
+
     return E_NOTIMPL;
 }
 
 static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count,
         MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status)
 {
+    struct wma_decoder *decoder = impl_from_IMFTransform(iface);
+    MFT_OUTPUT_STREAM_INFO info;
+    HRESULT hr;
+
     FIXME("iface %p, flags %#lx, count %lu, samples %p, status %p stub!\n", iface, flags, count, samples, status);
+
+    if (count > 1)
+        return E_INVALIDARG;
+
+    if (!decoder->wg_transform)
+        return MF_E_TRANSFORM_TYPE_NOT_SET;
+
+    if (FAILED(hr = IMFTransform_GetOutputStreamInfo(iface, 0, &info)))
+        return hr;
+
+    *status = 0;
+    samples[0].dwStatus = 0;
+    if (!samples[0].pSample)
+    {
+        samples[0].dwStatus = MFT_OUTPUT_DATA_BUFFER_NO_SAMPLE;
+        return MF_E_TRANSFORM_NEED_MORE_INPUT;
+    }
+
     return E_NOTIMPL;
 }
 
-- 
2.34.1




More information about the wine-devel mailing list