Anton Baskanov : winegstreamer: Implement Receive() for MPEG audio decoder sink.

Alexandre Julliard julliard at winehq.org
Fri May 6 15:38:39 CDT 2022


Module: wine
Branch: master
Commit: 6eca6ad68644639ef54706363dcbb2d62962da8f
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=6eca6ad68644639ef54706363dcbb2d62962da8f

Author: Anton Baskanov <baskanov at gmail.com>
Date:   Thu May  5 17:24:36 2022 -0500

winegstreamer: Implement Receive() for MPEG audio decoder sink.

Signed-off-by: Anton Baskanov <baskanov at gmail.com>
Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/quartz/tests/mpegaudio.c         | 10 ++--
 dlls/winegstreamer/quartz_transform.c | 86 +++++++++++++++++++++++++++++++++++
 2 files changed, 91 insertions(+), 5 deletions(-)

diff --git a/dlls/quartz/tests/mpegaudio.c b/dlls/quartz/tests/mpegaudio.c
index b34f09e137f..105469edaf1 100644
--- a/dlls/quartz/tests/mpegaudio.c
+++ b/dlls/quartz/tests/mpegaudio.c
@@ -1095,19 +1095,19 @@ static void test_sample_processing(IMediaControl *control, IMemInputPin *input,
     ok(hr == S_OK, "Got hr %#lx.\n", hr);
 
     hr = IMemInputPin_Receive(input, sample);
-    todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
+    ok(hr == S_OK, "Got hr %#lx.\n", hr);
     hr = IMemInputPin_Receive(input, sample);
-    todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
+    ok(hr == S_OK, "Got hr %#lx.\n", hr);
     hr = IMemInputPin_Receive(input, sample);
-    todo_wine ok(hr == S_OK, "Got hr %#lx.\n", hr);
-    todo_wine ok(sink->got_sample >= 1, "Got %u calls to Receive().\n", sink->got_sample);
+    ok(hr == S_OK, "Got hr %#lx.\n", hr);
+    ok(sink->got_sample >= 1, "Got %u calls to Receive().\n", sink->got_sample);
     sink->got_sample = 0;
 
     hr = IMediaControl_Stop(control);
     ok(hr == S_OK, "Got hr %#lx.\n", hr);
 
     hr = IMemInputPin_Receive(input, sample);
-    todo_wine ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
+    ok(hr == VFW_E_WRONG_STATE, "Got hr %#lx.\n", hr);
 
     IMediaSample_Release(sample);
     IMemAllocator_Release(allocator);
diff --git a/dlls/winegstreamer/quartz_transform.c b/dlls/winegstreamer/quartz_transform.c
index ab61e5eab94..5019cc6032b 100644
--- a/dlls/winegstreamer/quartz_transform.c
+++ b/dlls/winegstreamer/quartz_transform.c
@@ -20,6 +20,8 @@
 
 #include "gst_private.h"
 
+#include "mferror.h"
+
 WINE_DEFAULT_DEBUG_CHANNEL(quartz);
 WINE_DECLARE_DEBUG_CHANNEL(winediag);
 
@@ -137,10 +139,94 @@ static HRESULT transform_sink_query_interface(struct strmbase_pin *pin, REFIID i
     return S_OK;
 }
 
+static HRESULT WINAPI transform_sink_receive(struct strmbase_sink *pin, IMediaSample *sample)
+{
+    struct transform *filter = impl_from_strmbase_filter(pin->pin.filter);
+    struct wg_sample input_wg_sample = {0};
+    HRESULT hr;
+
+    /* We do not expect pin connection state to change while the filter is
+     * running. This guarantee is necessary, since otherwise we would have to
+     * take the filter lock, and we can't take the filter lock from a streaming
+     * thread. */
+    if (!filter->source.pMemInputPin)
+    {
+        WARN("Source is not connected, returning VFW_E_NOT_CONNECTED.\n");
+        return VFW_E_NOT_CONNECTED;
+    }
+
+    if (filter->filter.state == State_Stopped)
+        return VFW_E_WRONG_STATE;
+
+    if (filter->sink.flushing)
+        return S_FALSE;
+
+    input_wg_sample.max_size = IMediaSample_GetSize(sample);
+    input_wg_sample.size = IMediaSample_GetActualDataLength(sample);
+
+    hr = IMediaSample_GetPointer(sample, &input_wg_sample.data);
+    if (FAILED(hr))
+        return hr;
+
+    hr = wg_transform_push_data(filter->transform, &input_wg_sample);
+    if (FAILED(hr))
+        return hr;
+
+    for (;;)
+    {
+        struct wg_sample output_wg_sample = {0};
+        IMediaSample *output_sample;
+
+        hr = IMemAllocator_GetBuffer(filter->source.pAllocator, &output_sample, NULL, NULL, 0);
+        if (FAILED(hr))
+            return hr;
+
+        output_wg_sample.max_size = IMediaSample_GetSize(output_sample);
+
+        hr = IMediaSample_GetPointer(output_sample, &output_wg_sample.data);
+        if (FAILED(hr))
+        {
+            IMediaSample_Release(output_sample);
+            return hr;
+        }
+
+        hr = wg_transform_read_data(filter->transform, &output_wg_sample);
+        if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT)
+        {
+            IMediaSample_Release(output_sample);
+            break;
+        }
+        if (FAILED(hr))
+        {
+            IMediaSample_Release(output_sample);
+            return hr;
+        }
+
+        hr = IMediaSample_SetActualDataLength(output_sample, output_wg_sample.size);
+        if (FAILED(hr))
+        {
+            IMediaSample_Release(output_sample);
+            return hr;
+        }
+
+        hr = IMemInputPin_Receive(filter->source.pMemInputPin, output_sample);
+        if (FAILED(hr))
+        {
+            IMediaSample_Release(output_sample);
+            return hr;
+        }
+
+        IMediaSample_Release(output_sample);
+    }
+
+    return S_OK;
+}
+
 static const struct strmbase_sink_ops sink_ops =
 {
     .base.pin_query_accept = transform_sink_query_accept,
     .base.pin_query_interface = transform_sink_query_interface,
+    .pfnReceive = transform_sink_receive,
 };
 
 static HRESULT transform_source_query_accept(struct strmbase_pin *pin, const AM_MEDIA_TYPE *mt)




More information about the wine-cvs mailing list