Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/winegstreamer/wm_syncreader.c | 13 +++++++++---- dlls/wmvcore/tests/wmvcore.c | 4 ++-- 2 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/dlls/winegstreamer/wm_syncreader.c b/dlls/winegstreamer/wm_syncreader.c index bb98a60ad48..32b668f68c6 100644 --- a/dlls/winegstreamer/wm_syncreader.c +++ b/dlls/winegstreamer/wm_syncreader.c @@ -85,11 +85,16 @@ static HRESULT WINAPI WMSyncReader_GetNextSample(IWMSyncReader2 *iface, WORD str return E_NOTIMPL; }
-static HRESULT WINAPI WMSyncReader_GetOutputCount(IWMSyncReader2 *iface, DWORD *outputs) +static HRESULT WINAPI WMSyncReader_GetOutputCount(IWMSyncReader2 *iface, DWORD *count) { - struct sync_reader *This = impl_from_IWMSyncReader2(iface); - FIXME("(%p)->(%p): stub!\n", This, outputs); - return E_NOTIMPL; + struct sync_reader *reader = impl_from_IWMSyncReader2(iface); + + TRACE("reader %p, count %p.\n", reader, count); + + EnterCriticalSection(&reader->reader.cs); + *count = reader->reader.stream_count; + LeaveCriticalSection(&reader->reader.cs); + return S_OK; }
static HRESULT WINAPI WMSyncReader_GetOutputFormat(IWMSyncReader2 *iface, DWORD output_num, DWORD format_num, diff --git a/dlls/wmvcore/tests/wmvcore.c b/dlls/wmvcore/tests/wmvcore.c index ad58f53d552..5576018b1d6 100644 --- a/dlls/wmvcore/tests/wmvcore.c +++ b/dlls/wmvcore/tests/wmvcore.c @@ -463,8 +463,8 @@ static void test_sync_reader_streaming(void)
count = 0xdeadbeef; hr = IWMSyncReader_GetOutputCount(reader, &count); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine ok(count == 2, "Got count %u.\n", count); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(count == 2, "Got count %u.\n", count);
for (i = 0; i < 2; ++i) {
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/winegstreamer/gst_private.h | 7 ++ dlls/winegstreamer/wm_reader.c | 192 ++++++++++++++++++++++++++++++- dlls/wmvcore/tests/wmvcore.c | 43 ++++--- 3 files changed, 217 insertions(+), 25 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 86ddc3c85c8..063f01e5524 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -113,6 +113,12 @@ HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HI
HRESULT audio_converter_create(REFIID riid, void **ret) DECLSPEC_HIDDEN;
+struct wm_stream +{ + struct wm_reader *reader; + struct wg_parser_stream *wg_stream; +}; + struct wm_reader { IWMHeaderInfo3 IWMHeaderInfo3_iface; @@ -129,6 +135,7 @@ struct wm_reader bool read_thread_shutdown; struct wg_parser *wg_parser;
+ struct wm_stream *streams; WORD stream_count;
const struct wm_reader_ops *ops; diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c index 689d2232b73..f649a5cc518 100644 --- a/dlls/winegstreamer/wm_reader.c +++ b/dlls/winegstreamer/wm_reader.c @@ -20,6 +20,148 @@
WINE_DEFAULT_DEBUG_CHANNEL(wmvcore);
+struct stream_config +{ + IWMStreamConfig IWMStreamConfig_iface; + LONG refcount; + + const struct wm_stream *stream; +}; + +static struct stream_config *impl_from_IWMStreamConfig(IWMStreamConfig *iface) +{ + return CONTAINING_RECORD(iface, struct stream_config, IWMStreamConfig_iface); +} + +static HRESULT WINAPI stream_config_QueryInterface(IWMStreamConfig *iface, REFIID iid, void **out) +{ + struct stream_config *config = impl_from_IWMStreamConfig(iface); + + TRACE("config %p, iid %s, out %p.\n", config, debugstr_guid(iid), out); + + if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IWMStreamConfig)) + *out = &config->IWMStreamConfig_iface; + else + { + *out = NULL; + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown *)*out); + return S_OK; +} + +static ULONG WINAPI stream_config_AddRef(IWMStreamConfig *iface) +{ + struct stream_config *config = impl_from_IWMStreamConfig(iface); + ULONG refcount = InterlockedIncrement(&config->refcount); + + TRACE("%p increasing refcount to %u.\n", config, refcount); + + return refcount; +} + +static ULONG WINAPI stream_config_Release(IWMStreamConfig *iface) +{ + struct stream_config *config = impl_from_IWMStreamConfig(iface); + ULONG refcount = InterlockedDecrement(&config->refcount); + + TRACE("%p decreasing refcount to %u.\n", config, refcount); + + if (!refcount) + { + IWMProfile3_Release(&config->stream->reader->IWMProfile3_iface); + free(config); + } + + return refcount; +} + +static HRESULT WINAPI stream_config_GetStreamType(IWMStreamConfig *iface, GUID *type) +{ + FIXME("iface %p, type %p, stub!\n", iface, type); + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_config_GetStreamNumber(IWMStreamConfig *iface, WORD *number) +{ + FIXME("iface %p, number %p, stub!\n", iface, number); + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_config_SetStreamNumber(IWMStreamConfig *iface, WORD number) +{ + FIXME("iface %p, number %u, stub!\n", iface, number); + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_config_GetStreamName(IWMStreamConfig *iface, WCHAR *name, WORD *len) +{ + FIXME("iface %p, name %p, len %p, stub!\n", iface, name, len); + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_config_SetStreamName(IWMStreamConfig *iface, const WCHAR *name) +{ + FIXME("iface %p, name %s, stub!\n", iface, debugstr_w(name)); + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_config_GetConnectionName(IWMStreamConfig *iface, WCHAR *name, WORD *len) +{ + FIXME("iface %p, name %p, len %p, stub!\n", iface, name, len); + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_config_SetConnectionName(IWMStreamConfig *iface, const WCHAR *name) +{ + FIXME("iface %p, name %s, stub!\n", iface, debugstr_w(name)); + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_config_GetBitrate(IWMStreamConfig *iface, DWORD *bitrate) +{ + FIXME("iface %p, bitrate %p, stub!\n", iface, bitrate); + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_config_SetBitrate(IWMStreamConfig *iface, DWORD bitrate) +{ + FIXME("iface %p, bitrate %u, stub!\n", iface, bitrate); + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_config_GetBufferWindow(IWMStreamConfig *iface, DWORD *window) +{ + FIXME("iface %p, window %p, stub!\n", iface, window); + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_config_SetBufferWindow(IWMStreamConfig *iface, DWORD window) +{ + FIXME("iface %p, window %u, stub!\n", iface, window); + return E_NOTIMPL; +} + +static const IWMStreamConfigVtbl stream_config_vtbl = +{ + stream_config_QueryInterface, + stream_config_AddRef, + stream_config_Release, + stream_config_GetStreamType, + stream_config_GetStreamNumber, + stream_config_SetStreamNumber, + stream_config_GetStreamName, + stream_config_SetStreamName, + stream_config_GetConnectionName, + stream_config_SetConnectionName, + stream_config_GetBitrate, + stream_config_SetBitrate, + stream_config_GetBufferWindow, + stream_config_SetBufferWindow, +}; + static DWORD CALLBACK read_thread(void *arg) { struct wm_reader *reader = arg; @@ -203,8 +345,36 @@ static HRESULT WINAPI profile_GetStreamCount(IWMProfile3 *iface, DWORD *count)
static HRESULT WINAPI profile_GetStream(IWMProfile3 *iface, DWORD index, IWMStreamConfig **config) { - FIXME("iface %p, index %d, config %p, stub!\n", iface, index, config); - return E_NOTIMPL; + struct wm_reader *reader = impl_from_IWMProfile3(iface); + struct stream_config *object; + + TRACE("reader %p, index %u, config %p.\n", reader, index, config); + + EnterCriticalSection(&reader->cs); + + if (index >= reader->stream_count) + { + LeaveCriticalSection(&reader->cs); + WARN("Index %u exceeds stream count %u; returning E_INVALIDARG.\n", index, reader->stream_count); + return E_INVALIDARG; + } + + if (!(object = calloc(1, sizeof(*object)))) + { + LeaveCriticalSection(&reader->cs); + return E_OUTOFMEMORY; + } + + object->IWMStreamConfig_iface.lpVtbl = &stream_config_vtbl; + object->refcount = 1; + object->stream = &reader->streams[index]; + IWMProfile3_AddRef(&reader->IWMProfile3_iface); + + LeaveCriticalSection(&reader->cs); + + TRACE("Created stream config %p.\n", object); + *config = &object->IWMStreamConfig_iface; + return S_OK; }
static HRESULT WINAPI profile_GetStreamByNumber(IWMProfile3 *iface, WORD stream_number, IWMStreamConfig **config) @@ -830,6 +1000,7 @@ HRESULT wm_reader_open_stream(struct wm_reader *reader, IStream *stream) struct wg_parser *wg_parser; STATSTG stat; HRESULT hr; + WORD i;
if (FAILED(hr = IStream_Stat(stream, &stat, STATFLAG_NONAME))) { @@ -859,9 +1030,26 @@ HRESULT wm_reader_open_stream(struct wm_reader *reader, IStream *stream)
reader->stream_count = wg_parser_get_stream_count(reader->wg_parser);
+ if (!(reader->streams = calloc(reader->stream_count, sizeof(*reader->streams)))) + { + hr = E_OUTOFMEMORY; + goto out_disconnect_parser; + } + + for (i = 0; i < reader->stream_count; ++i) + { + struct wm_stream *stream = &reader->streams[i]; + + stream->wg_stream = wg_parser_get_stream(reader->wg_parser, i); + stream->reader = reader; + } + LeaveCriticalSection(&reader->cs); return S_OK;
+out_disconnect_parser: + wg_parser_disconnect(reader->wg_parser); + out_shutdown_thread: reader->read_thread_shutdown = true; WaitForSingleObject(reader->read_thread, INFINITE); diff --git a/dlls/wmvcore/tests/wmvcore.c b/dlls/wmvcore/tests/wmvcore.c index 5576018b1d6..8bd477dba65 100644 --- a/dlls/wmvcore/tests/wmvcore.c +++ b/dlls/wmvcore/tests/wmvcore.c @@ -469,31 +469,28 @@ static void test_sync_reader_streaming(void) for (i = 0; i < 2; ++i) { hr = IWMProfile_GetStream(profile, i, &config); + ok(hr == S_OK, "Got hr %#x.\n", hr); + + hr = IWMProfile_GetStream(profile, i, &config2); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(config2 != config, "Expected different objects.\n"); + ref = IWMStreamConfig_Release(config2); + ok(!ref, "Got outstanding refcount %d.\n", ref); + + stream_numbers[i] = 0xdead; + hr = IWMStreamConfig_GetStreamNumber(config, &stream_numbers[i]); todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + todo_wine ok(stream_numbers[i] == i + 1, "Got stream number %u.\n", stream_numbers[i]);
- if (hr == S_OK) - { - hr = IWMProfile_GetStream(profile, i, &config2); - ok(hr == S_OK, "Got hr %#x.\n", hr); - ok(config2 != config, "Expected different objects.\n"); - ref = IWMStreamConfig_Release(config2); - ok(!ref, "Got outstanding refcount %d.\n", ref); - - stream_numbers[i] = 0xdead; - hr = IWMStreamConfig_GetStreamNumber(config, &stream_numbers[i]); - ok(hr == S_OK, "Got hr %#x.\n", hr); - ok(stream_numbers[i] == i + 1, "Got stream number %u.\n", stream_numbers[i]); - - ref = IWMStreamConfig_Release(config); - ok(!ref, "Got outstanding refcount %d.\n", ref); - } + ref = IWMStreamConfig_Release(config); + ok(!ref, "Got outstanding refcount %d.\n", ref);
hr = IWMSyncReader_SetReadStreamSamples(reader, stream_numbers[i], FALSE); todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); }
hr = IWMProfile_GetStream(profile, 2, &config); - todo_wine ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr); + ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
while (!eos[0] || !eos[1]) { @@ -699,12 +696,7 @@ static void test_sync_reader_types(void) winetest_push_context("Stream %u", i);
hr = IWMProfile_GetStream(profile, i, &config); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); - if (hr != S_OK) - { - winetest_pop_context(); - continue; - } + ok(hr == S_OK, "Got hr %#x.\n", hr);
stream_number = 0xdead; hr = IWMStreamConfig_GetStreamNumber(config, &stream_number); @@ -733,6 +725,11 @@ static void test_sync_reader_types(void)
hr = IWMSyncReader_GetOutputProps(reader, output_number, &output_props); todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + if (hr != S_OK) + { + winetest_pop_context(); + continue; + }
ret_size = sizeof(mt_buffer); hr = IWMOutputMediaProps_GetMediaType(output_props, mt, &ret_size);
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/winegstreamer/gst_private.h | 1 + dlls/winegstreamer/wm_reader.c | 9 +++++++-- dlls/wmvcore/tests/wmvcore.c | 10 +++++----- 3 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 063f01e5524..8b5183a95ee 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -117,6 +117,7 @@ struct wm_stream { struct wm_reader *reader; struct wg_parser_stream *wg_stream; + WORD index; };
struct wm_reader diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c index f649a5cc518..682f9a2ae50 100644 --- a/dlls/winegstreamer/wm_reader.c +++ b/dlls/winegstreamer/wm_reader.c @@ -86,8 +86,12 @@ static HRESULT WINAPI stream_config_GetStreamType(IWMStreamConfig *iface, GUID *
static HRESULT WINAPI stream_config_GetStreamNumber(IWMStreamConfig *iface, WORD *number) { - FIXME("iface %p, number %p, stub!\n", iface, number); - return E_NOTIMPL; + struct stream_config *config = impl_from_IWMStreamConfig(iface); + + TRACE("config %p, number %p.\n", config, number); + + *number = config->stream->index + 1; + return S_OK; }
static HRESULT WINAPI stream_config_SetStreamNumber(IWMStreamConfig *iface, WORD number) @@ -1042,6 +1046,7 @@ HRESULT wm_reader_open_stream(struct wm_reader *reader, IStream *stream)
stream->wg_stream = wg_parser_get_stream(reader->wg_parser, i); stream->reader = reader; + stream->index = i; }
LeaveCriticalSection(&reader->cs); diff --git a/dlls/wmvcore/tests/wmvcore.c b/dlls/wmvcore/tests/wmvcore.c index 8bd477dba65..247b03564f1 100644 --- a/dlls/wmvcore/tests/wmvcore.c +++ b/dlls/wmvcore/tests/wmvcore.c @@ -479,8 +479,8 @@ static void test_sync_reader_streaming(void)
stream_numbers[i] = 0xdead; hr = IWMStreamConfig_GetStreamNumber(config, &stream_numbers[i]); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine ok(stream_numbers[i] == i + 1, "Got stream number %u.\n", stream_numbers[i]); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(stream_numbers[i] == i + 1, "Got stream number %u.\n", stream_numbers[i]);
ref = IWMStreamConfig_Release(config); ok(!ref, "Got outstanding refcount %d.\n", ref); @@ -700,8 +700,8 @@ static void test_sync_reader_types(void)
stream_number = 0xdead; hr = IWMStreamConfig_GetStreamNumber(config, &stream_number); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine ok(stream_number == i + 1, "Got stream number %u.\n", stream_number); + ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(stream_number == i + 1, "Got stream number %u.\n", stream_number);
hr = IWMStreamConfig_GetStreamType(config, &majortype); todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); @@ -721,7 +721,7 @@ static void test_sync_reader_types(void) stream_number2 = 0xdead; hr = IWMSyncReader_GetStreamNumberForOutput(reader, output_number, &stream_number2); ok(hr == S_OK, "Got hr %#x.\n", hr); - ok(stream_number2 == stream_number, "Expected stream number %u, got %u.\n", stream_number, stream_number2); + todo_wine ok(stream_number2 == stream_number, "Expected stream number %u, got %u.\n", stream_number, stream_number2);
hr = IWMSyncReader_GetOutputProps(reader, output_number, &output_props); todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/winegstreamer/wm_syncreader.c | 12 ++++++++---- dlls/wmvcore/tests/wmvcore.c | 2 +- 2 files changed, 9 insertions(+), 5 deletions(-)
diff --git a/dlls/winegstreamer/wm_syncreader.c b/dlls/winegstreamer/wm_syncreader.c index 32b668f68c6..da18b4c9a2f 100644 --- a/dlls/winegstreamer/wm_syncreader.c +++ b/dlls/winegstreamer/wm_syncreader.c @@ -112,11 +112,15 @@ static HRESULT WINAPI WMSyncReader_GetOutputFormatCount(IWMSyncReader2 *iface, D return E_NOTIMPL; }
-static HRESULT WINAPI WMSyncReader_GetOutputNumberForStream(IWMSyncReader2 *iface, WORD stream_num, DWORD *output_num) +static HRESULT WINAPI WMSyncReader_GetOutputNumberForStream(IWMSyncReader2 *iface, + WORD stream_number, DWORD *output) { - struct sync_reader *This = impl_from_IWMSyncReader2(iface); - FIXME("(%p)->(%u %p): stub!\n", This, stream_num, output_num); - return E_NOTIMPL; + struct sync_reader *reader = impl_from_IWMSyncReader2(iface); + + TRACE("reader %p, stream_number %u, output %p.\n", reader, stream_number, output); + + *output = stream_number - 1; + return S_OK; }
static HRESULT WINAPI WMSyncReader_GetOutputProps(IWMSyncReader2 *iface, DWORD output_num, IWMOutputMediaProps **output) diff --git a/dlls/wmvcore/tests/wmvcore.c b/dlls/wmvcore/tests/wmvcore.c index 247b03564f1..51fa3ae3b1b 100644 --- a/dlls/wmvcore/tests/wmvcore.c +++ b/dlls/wmvcore/tests/wmvcore.c @@ -715,7 +715,7 @@ static void test_sync_reader_types(void)
output_number = 0xdeadbeef; hr = IWMSyncReader_GetOutputNumberForStream(reader, stream_number, &output_number); - todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); + ok(hr == S_OK, "Got hr %#x.\n", hr); todo_wine ok(output_number == 1 - i, "Got output number %u.\n", output_number);
stream_number2 = 0xdead;
Signed-off-by: Zebediah Figura zfigura@codeweavers.com --- dlls/winegstreamer/wm_syncreader.c | 10 +++++++--- dlls/wmvcore/tests/wmvcore.c | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/dlls/winegstreamer/wm_syncreader.c b/dlls/winegstreamer/wm_syncreader.c index da18b4c9a2f..cb2e61a25bc 100644 --- a/dlls/winegstreamer/wm_syncreader.c +++ b/dlls/winegstreamer/wm_syncreader.c @@ -145,10 +145,14 @@ static HRESULT WINAPI WMSyncReader_GetReadStreamSamples(IWMSyncReader2 *iface, W return E_NOTIMPL; }
-static HRESULT WINAPI WMSyncReader_GetStreamNumberForOutput(IWMSyncReader2 *iface, DWORD output, WORD *stream_num) +static HRESULT WINAPI WMSyncReader_GetStreamNumberForOutput(IWMSyncReader2 *iface, + DWORD output, WORD *stream_number) { - struct sync_reader *This = impl_from_IWMSyncReader2(iface); - FIXME("(%p)->(%u %p): stub!\n", This, output, stream_num); + struct sync_reader *reader = impl_from_IWMSyncReader2(iface); + + TRACE("reader %p, output %u, stream_number %p.\n", reader, output, stream_number); + + *stream_number = output + 1; return S_OK; }
diff --git a/dlls/wmvcore/tests/wmvcore.c b/dlls/wmvcore/tests/wmvcore.c index 51fa3ae3b1b..385cda74aba 100644 --- a/dlls/wmvcore/tests/wmvcore.c +++ b/dlls/wmvcore/tests/wmvcore.c @@ -721,7 +721,7 @@ static void test_sync_reader_types(void) stream_number2 = 0xdead; hr = IWMSyncReader_GetStreamNumberForOutput(reader, output_number, &stream_number2); ok(hr == S_OK, "Got hr %#x.\n", hr); - todo_wine ok(stream_number2 == stream_number, "Expected stream number %u, got %u.\n", stream_number, stream_number2); + ok(stream_number2 == stream_number, "Expected stream number %u, got %u.\n", stream_number, stream_number2);
hr = IWMSyncReader_GetOutputProps(reader, output_number, &output_props); todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);