winegstreamer: Implement IWMProfile::GetStream().
Signed-off-by: Zebediah Figura <zfigura@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
8bd3c8bf5a
commit
40ced5e054
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue