From 894e0712459ec2d48b1298724776134d2a966f66 Mon Sep 17 00:00:00 2001 From: Zebediah Figura Date: Wed, 10 Nov 2021 19:05:48 -0600 Subject: [PATCH] winegstreamer: Implement IWMReaderAdvanced::SetReceiveStreamSamples(). Signed-off-by: Zebediah Figura Signed-off-by: Alexandre Julliard --- 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 810a800f016..91025ec103d 100644 --- a/dlls/winegstreamer/wm_reader.c +++ b/dlls/winegstreamer/wm_reader.c @@ -1750,9 +1750,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)) @@ -1773,7 +1770,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))) @@ -1951,6 +1948,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.11.4.GIT