[PATCH 3/5] winegstreamer: Implement IWMReaderAdvanced::SetReceiveStreamSamples().

Zebediah Figura zfigura at codeweavers.com
Wed Nov 10 19:05:48 CST 2021


Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 dlls/winegstreamer/gst_private.h    |  7 +++
 dlls/winegstreamer/wm_asyncreader.c | 20 +++++---
 dlls/winegstreamer/wm_reader.c      | 23 ++++++++--
 dlls/wmvcore/tests/wmvcore.c        | 71 ++++++++++++++++++++++++-----
 4 files changed, 100 insertions(+), 21 deletions(-)

diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index f1862515ebc..e31405a09ca 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -125,6 +125,11 @@ struct wm_stream
     WORD index;
     bool eos;
     bool allocate_output;
+    /* Note that we only pretend to read compressed samples, and instead output
+     * uncompressed samples regardless of whether we are configured to read
+     * compressed samples. Rather, the behaviour of the reader objects differs
+     * in nontrivial ways depending on this field. */
+    bool read_compressed;
 };
 
 struct wm_reader
@@ -180,6 +185,8 @@ void wm_reader_seek(struct wm_reader *reader, QWORD start, LONGLONG duration);
 HRESULT wm_reader_set_allocate_for_output(struct wm_reader *reader, DWORD output, BOOL allocate);
 HRESULT wm_reader_set_output_props(struct wm_reader *reader, DWORD output,
         IWMOutputMediaProps *props);
+HRESULT wm_reader_set_read_compressed(struct wm_reader *reader,
+        WORD stream_number, BOOL compressed);
 HRESULT wm_reader_set_streams_selected(struct wm_reader *reader, WORD count,
         const WORD *stream_numbers, const WMT_STREAM_SELECTION *selections);
 
diff --git a/dlls/winegstreamer/wm_asyncreader.c b/dlls/winegstreamer/wm_asyncreader.c
index e0547dfda60..9cf8a73eb53 100644
--- a/dlls/winegstreamer/wm_asyncreader.c
+++ b/dlls/winegstreamer/wm_asyncreader.c
@@ -129,7 +129,13 @@ static DWORD WINAPI stream_thread(void *arg)
                     }
                 }
 
-                IWMReaderCallback_OnSample(callback, i, pts, duration, flags, sample, reader->context);
+                if (stream->read_compressed)
+                    hr = IWMReaderCallbackAdvanced_OnStreamSample(reader->reader.callback_advanced,
+                            i + 1, pts, duration, flags, sample, reader->context);
+                else
+                    hr = IWMReaderCallback_OnSample(callback, i, pts, duration,
+                            flags, sample, reader->context);
+                TRACE("Callback returned %#x.\n", hr);
                 INSSBuffer_Release(sample);
                 all_eos = false;
             }
@@ -487,12 +493,14 @@ static HRESULT WINAPI WMReaderAdvanced_GetReceiveSelectionCallbacks(IWMReaderAdv
     return E_NOTIMPL;
 }
 
-static HRESULT WINAPI WMReaderAdvanced_SetReceiveStreamSamples(IWMReaderAdvanced6 *iface, WORD stream_num,
-        BOOL receive_stream_samples)
+static HRESULT WINAPI WMReaderAdvanced_SetReceiveStreamSamples(IWMReaderAdvanced6 *iface,
+        WORD stream_number, BOOL compressed)
 {
-    struct async_reader *This = impl_from_IWMReaderAdvanced6(iface);
-    FIXME("(%p)->(%d %x)\n", This, stream_num, receive_stream_samples);
-    return E_NOTIMPL;
+    struct async_reader *reader = impl_from_IWMReaderAdvanced6(iface);
+
+    TRACE("reader %p, stream_number %u, compressed %d.\n", reader, stream_number, compressed);
+
+    return wm_reader_set_read_compressed(&reader->reader, stream_number, compressed);
 }
 
 static HRESULT WINAPI WMReaderAdvanced_GetReceiveStreamSamples(IWMReaderAdvanced6 *iface, WORD stream_num,
diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c
index 09059c3a32b..c53fb8ea8ee 100644
--- a/dlls/winegstreamer/wm_reader.c
+++ b/dlls/winegstreamer/wm_reader.c
@@ -1772,9 +1772,6 @@ HRESULT wm_reader_get_stream_sample(struct wm_stream *stream,
     if (stream->eos)
         return NS_E_NO_MORE_SAMPLES;
 
-    if (!stream->allocate_output)
-        callback_advanced = NULL;
-
     for (;;)
     {
         if (!wg_parser_stream_get_event(wg_stream, &event))
@@ -1795,7 +1792,7 @@ HRESULT wm_reader_get_stream_sample(struct wm_stream *stream,
                 HRESULT hr;
                 BYTE *data;
 
-                if (callback_advanced)
+                if (callback_advanced && !stream->read_compressed && stream->allocate_output)
                 {
                     if (FAILED(hr = IWMReaderCallbackAdvanced_AllocateForOutput(callback_advanced,
                             stream->index, event.u.buffer.size, &sample, NULL)))
@@ -1973,6 +1970,24 @@ HRESULT wm_reader_set_allocate_for_output(struct wm_reader *reader, DWORD output
     return S_OK;
 }
 
+HRESULT wm_reader_set_read_compressed(struct wm_reader *reader, WORD stream_number, BOOL compressed)
+{
+    struct wm_stream *stream;
+
+    EnterCriticalSection(&reader->cs);
+
+    if (!(stream = wm_reader_get_stream_by_stream_number(reader, stream_number)))
+    {
+        LeaveCriticalSection(&reader->cs);
+        return E_INVALIDARG;
+    }
+
+    stream->read_compressed = compressed;
+
+    LeaveCriticalSection(&reader->cs);
+    return S_OK;
+}
+
 void wm_reader_init(struct wm_reader *reader, const struct wm_reader_ops *ops)
 {
     reader->IWMHeaderInfo3_iface.lpVtbl = &header_info_vtbl;
diff --git a/dlls/wmvcore/tests/wmvcore.c b/dlls/wmvcore/tests/wmvcore.c
index 07a465c7518..eb6e45b30ce 100644
--- a/dlls/wmvcore/tests/wmvcore.c
+++ b/dlls/wmvcore/tests/wmvcore.c
@@ -1348,6 +1348,7 @@ struct callback
     unsigned int got_closed, got_started, got_sample, got_end_of_streaming, got_eof;
     bool all_streams_off;
     bool allocated_samples;
+    bool read_compressed;
 };
 
 static struct callback *impl_from_IWMReaderCallback(IWMReaderCallback *iface)
@@ -1474,20 +1475,12 @@ static HRESULT WINAPI callback_OnStatus(IWMReaderCallback *iface, WMT_STATUS sta
     return S_OK;
 }
 
-static HRESULT WINAPI callback_OnSample(IWMReaderCallback *iface, DWORD output,
-        QWORD time, QWORD duration, DWORD flags, INSSBuffer *sample, void *context)
+static void check_async_sample(struct callback *callback, INSSBuffer *sample)
 {
-    struct callback *callback = impl_from_IWMReaderCallback(iface);
     DWORD size, capacity;
     BYTE *data, *data2;
     HRESULT hr;
 
-    if (winetest_debug > 1)
-        trace("%u: %04x: IWMReaderCallback::OnSample(output %u, time %I64u, duration %I64u, flags %#x)\n",
-                GetTickCount(), GetCurrentThreadId(), output, time, duration, flags);
-
-    ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context);
-
     if (callback->allocated_samples)
     {
         struct buffer *buffer = impl_from_INSSBuffer(sample);
@@ -1521,7 +1514,22 @@ static HRESULT WINAPI callback_OnSample(IWMReaderCallback *iface, DWORD output,
         ok(data2 == data, "Data pointers didn't match.\n");
         ok(size == capacity - 1, "Expected size %u, got %u.\n", capacity - 1, size);
     }
+}
 
+static HRESULT WINAPI callback_OnSample(IWMReaderCallback *iface, DWORD output,
+        QWORD time, QWORD duration, DWORD flags, INSSBuffer *sample, void *context)
+{
+    struct callback *callback = impl_from_IWMReaderCallback(iface);
+
+    if (winetest_debug > 1)
+        trace("%u: %04x: IWMReaderCallback::OnSample(output %u, time %I64u, duration %I64u, flags %#x)\n",
+                GetTickCount(), GetCurrentThreadId(), output, time, duration, flags);
+
+    ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context);
+
+    check_async_sample(callback, sample);
+
+    ok(!callback->read_compressed, "OnSample() should not be called when reading compressed samples.\n");
     ok(callback->got_started > 0, "Got %u WMT_STARTED callbacks.\n", callback->got_started);
     ok(!callback->got_eof, "Got %u WMT_EOF callbacks.\n", callback->got_eof);
     ++callback->got_sample;
@@ -1564,8 +1572,22 @@ static ULONG WINAPI callback_advanced_Release(IWMReaderCallbackAdvanced *iface)
 static HRESULT WINAPI callback_advanced_OnStreamSample(IWMReaderCallbackAdvanced *iface,
         WORD stream_number, QWORD pts, QWORD duration, DWORD flags, INSSBuffer *sample, void *context)
 {
-    ok(0, "Unexpected call.\n");
-    return E_NOTIMPL;
+    struct callback *callback = impl_from_IWMReaderCallbackAdvanced(iface);
+
+    if (winetest_debug > 1)
+        trace("%u: %04x: IWMReaderCallbackAdvanced::OnStreamSample(stream %u, pts %I64u, duration %I64u, flags %#x)\n",
+                GetTickCount(), GetCurrentThreadId(), stream_number, pts, duration, flags);
+
+    ok(context == (void *)0xfacade, "Got unexpected context %p.\n", context);
+
+    check_async_sample(callback, sample);
+
+    ok(callback->read_compressed, "OnStreamSample() should not be called unless reading compressed samples.\n");
+    ok(callback->got_started > 0, "Got %u WMT_STARTED callbacks.\n", callback->got_started);
+    ok(!callback->got_eof, "Got %u WMT_EOF callbacks.\n", callback->got_eof);
+    ++callback->got_sample;
+
+    return S_OK;
 }
 
 static HRESULT WINAPI callback_advanced_OnTime(IWMReaderCallbackAdvanced *iface, QWORD time, void *context)
@@ -1915,6 +1937,32 @@ static void test_async_reader_selection(IWMReader *reader,
     ok(hr == S_OK, "Got hr %#x.\n", hr);
 }
 
+static void test_async_reader_compressed(IWMReader *reader,
+        IWMReaderAdvanced2 *advanced, struct callback *callback)
+{
+    HRESULT hr;
+
+    hr = IWMReaderAdvanced2_SetReceiveStreamSamples(advanced, 0, TRUE);
+    ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
+
+    hr = IWMReaderAdvanced2_SetReceiveStreamSamples(advanced, 3, TRUE);
+    ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
+
+    hr = IWMReaderAdvanced2_SetReceiveStreamSamples(advanced, 1, TRUE);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    hr = IWMReaderAdvanced2_SetReceiveStreamSamples(advanced, 2, TRUE);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+
+    callback->read_compressed = true;
+    run_async_reader(reader, advanced, callback);
+    callback->read_compressed = false;
+
+    hr = IWMReaderAdvanced2_SetReceiveStreamSamples(advanced, 1, FALSE);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+    hr = IWMReaderAdvanced2_SetReceiveStreamSamples(advanced, 2, FALSE);
+    ok(hr == S_OK, "Got hr %#x.\n", hr);
+}
+
 static void test_async_reader_streaming(void)
 {
     const WCHAR *filename = load_resource(L"test.wmv");
@@ -2007,6 +2055,7 @@ static void test_async_reader_streaming(void)
     test_reader_attributes(profile);
     test_async_reader_selection(reader, advanced, &callback);
     test_async_reader_allocate(reader, advanced, &callback);
+    test_async_reader_compressed(reader, advanced, &callback);
 
     hr = IWMReader_Close(reader);
     ok(hr == S_OK, "Got hr %#x.\n", hr);
-- 
2.33.0




More information about the wine-devel mailing list