[PATCH 5/5] winegstreamer: Implement H264 decoder Process(Input|Output).

Rémi Bernon rbernon at codeweavers.com
Wed Mar 16 04:40:54 CDT 2022


Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/mf/tests/mf.c                |  3 --
 dlls/winegstreamer/h264_decoder.c | 58 ++++++++++++++++++++++++++++---
 2 files changed, 54 insertions(+), 7 deletions(-)

diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index 0df524b4e16..0c1065572ca 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -6821,7 +6821,6 @@ static void test_h264_decoder(void)
     status = 0;
     memset(&output, 0, sizeof(output));
     hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status);
-    todo_wine
     ok(hr == E_INVALIDARG || hr == MF_E_TRANSFORM_NEED_MORE_INPUT, "ProcessOutput returned %#lx\n", hr);
     ok(output.dwStreamID == 0, "got dwStreamID %lu\n", output.dwStreamID);
     ok(!output.pSample, "got pSample %p\n", output.pSample);
@@ -6849,14 +6848,12 @@ static void test_h264_decoder(void)
         ok(ret == 0, "Release returned %lu\n", ret);
 
         hr = IMFTransform_ProcessInput(transform, 0, sample, 0);
-        todo_wine
         ok(hr == S_OK, "ProcessInput returned %#lx\n", hr);
         ret = IMFSample_Release(sample);
         ok(ret <= 1, "Release returned %lu\n", ret);
         sample = next_h264_sample(&h264_encoded_data, &h264_encoded_data_len);
 
         hr = IMFTransform_ProcessInput(transform, 0, sample, 0);
-        todo_wine
         ok(hr == S_OK, "ProcessInput returned %#lx\n", hr);
         ret = IMFSample_Release(sample);
         ok(ret <= 1, "Release returned %lu\n", ret);
diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c
index 4edd4cdf39c..1e805693c7c 100644
--- a/dlls/winegstreamer/h264_decoder.c
+++ b/dlls/winegstreamer/h264_decoder.c
@@ -496,15 +496,65 @@ static HRESULT WINAPI transform_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_
 
 static HRESULT WINAPI transform_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags)
 {
-    FIXME("iface %p, id %#lx, sample %p, flags %#lx stub!\n", iface, id, sample, flags);
-    return E_NOTIMPL;
+    struct h264_decoder *decoder = impl_from_IMFTransform(iface);
+    struct wg_sample *wg_sample;
+    MFT_INPUT_STREAM_INFO info;
+    HRESULT hr;
+
+    TRACE("iface %p, id %#lx, sample %p, flags %#lx.\n", iface, id, sample, flags);
+
+    if (FAILED(hr = IMFTransform_GetInputStreamInfo(iface, 0, &info)))
+        return hr;
+
+    if (!decoder->wg_transform)
+        return MF_E_TRANSFORM_TYPE_NOT_SET;
+
+    if (FAILED(hr = mf_create_wg_sample(sample, &wg_sample)))
+        return hr;
+
+    hr = wg_transform_push_data(decoder->wg_transform, wg_sample);
+
+    mf_destroy_wg_sample(wg_sample);
+    return hr;
 }
 
 static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count,
         MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status)
 {
-    FIXME("iface %p, flags %#lx, count %lu, samples %p, status %p stub!\n", iface, flags, count, samples, status);
-    return E_NOTIMPL;
+    struct h264_decoder *decoder = impl_from_IMFTransform(iface);
+    MFT_OUTPUT_STREAM_INFO info;
+    struct wg_sample *wg_sample;
+    UINT64 frame_rate;
+    HRESULT hr;
+
+    TRACE("iface %p, flags %#lx, count %lu, samples %p, status %p.\n", iface, flags, count, samples, status);
+
+    if (count != 1)
+        return E_INVALIDARG;
+
+    if (FAILED(hr = IMFTransform_GetOutputStreamInfo(iface, 0, &info)))
+        return hr;
+
+    if (!decoder->wg_transform)
+        return MF_E_TRANSFORM_TYPE_NOT_SET;
+
+    if (FAILED(IMFMediaType_GetUINT64(decoder->output_type, &MF_MT_FRAME_RATE, &frame_rate)))
+        frame_rate = (UINT64)30000 << 32 | 1001;
+
+    *status = 0;
+    samples[0].dwStatus = 0;
+    if (!samples[0].pSample) return E_INVALIDARG;
+
+    if (FAILED(hr = mf_create_wg_sample(samples[0].pSample, &wg_sample)))
+        return hr;
+
+    if (wg_sample->max_size < info.cbSize)
+        hr = MF_E_BUFFERTOOSMALL;
+    else
+        hr = wg_transform_read_data(decoder->wg_transform, wg_sample);
+
+    mf_destroy_wg_sample(wg_sample);
+    return hr;
 }
 
 static const IMFTransformVtbl transform_vtbl =
-- 
2.35.1




More information about the wine-devel mailing list