Controlling lifetime from the sync / async reader side.
From: Rémi Bernon rbernon@codeweavers.com
Controlling lifetime from the sync / async reader side. --- dlls/winegstreamer/gst_private.h | 14 +- dlls/winegstreamer/wm_asyncreader.c | 242 ++++++++++++++-------------- dlls/winegstreamer/wm_reader.c | 107 +++--------- dlls/winegstreamer/wm_syncreader.c | 92 ++++++----- 4 files changed, 193 insertions(+), 262 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 8e761758da4..f60892e00f1 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -168,9 +168,9 @@ struct wm_reader IWMProfile3 IWMProfile3_iface; IWMReaderPlaylistBurn IWMReaderPlaylistBurn_iface; IWMReaderTimecode IWMReaderTimecode_iface; - LONG refcount; - CRITICAL_SECTION cs; + IUnknown *outer;
+ CRITICAL_SECTION cs; QWORD start_time;
IStream *source_stream; @@ -181,14 +181,6 @@ struct wm_reader
struct wm_stream *streams; WORD stream_count; - - const struct wm_reader_ops *ops; -}; - -struct wm_reader_ops -{ - void *(*query_interface)(struct wm_reader *reader, REFIID iid); - void (*destroy)(struct wm_reader *reader); };
void wm_reader_cleanup(struct wm_reader *reader); @@ -205,7 +197,7 @@ HRESULT wm_reader_get_stream_sample(struct wm_reader *reader, IWMReaderCallbackA INSSBuffer **ret_sample, QWORD *pts, QWORD *duration, DWORD *flags, WORD *ret_stream_number); HRESULT wm_reader_get_stream_selection(struct wm_reader *reader, WORD stream_number, WMT_STREAM_SELECTION *selection); -void wm_reader_init(struct wm_reader *reader, const struct wm_reader_ops *ops); +void wm_reader_init(IUnknown *outer, struct wm_reader *reader); HRESULT wm_reader_open_file(struct wm_reader *reader, const WCHAR *filename); HRESULT wm_reader_open_stream(struct wm_reader *reader, IStream *stream); void wm_reader_seek(struct wm_reader *reader, QWORD start, LONGLONG duration); diff --git a/dlls/winegstreamer/wm_asyncreader.c b/dlls/winegstreamer/wm_asyncreader.c index 5b09bc616a6..c9d134d5245 100644 --- a/dlls/winegstreamer/wm_asyncreader.c +++ b/dlls/winegstreamer/wm_asyncreader.c @@ -54,8 +54,6 @@ struct sample
struct async_reader { - struct wm_reader reader; - IWMReader IWMReader_iface; IWMReaderAdvanced6 IWMReaderAdvanced6_iface; IWMReaderAccelerator IWMReaderAccelerator_iface; @@ -63,6 +61,8 @@ struct async_reader IWMReaderStreamClock IWMReaderStreamClock_iface; IWMReaderTypeNegotiation IWMReaderTypeNegotiation_iface; IReferenceClock IReferenceClock_iface; + struct wm_reader reader; + LONG refcount;
CRITICAL_SECTION cs;
@@ -366,21 +366,92 @@ static HRESULT WINAPI WMReader_QueryInterface(IWMReader *iface, REFIID iid, void { struct async_reader *reader = impl_from_IWMReader(iface);
- return IWMProfile3_QueryInterface(&reader->reader.IWMProfile3_iface, iid, out); + TRACE("reader %p, iid %s, out %p.\n", reader, debugstr_guid(iid), out); + + if (IsEqualIID(iid, &IID_IUnknown) + || IsEqualIID(iid, &IID_IWMReader)) + *out = &reader->IWMReader_iface; + else if (IsEqualIID(iid, &IID_IWMReaderAccelerator)) + *out = &reader->IWMReaderAccelerator_iface; + else if (IsEqualIID(iid, &IID_IWMReaderAdvanced) + || IsEqualIID(iid, &IID_IWMReaderAdvanced2) + || IsEqualIID(iid, &IID_IWMReaderAdvanced3) + || IsEqualIID(iid, &IID_IWMReaderAdvanced4) + || IsEqualIID(iid, &IID_IWMReaderAdvanced5) + || IsEqualIID(iid, &IID_IWMReaderAdvanced6)) + *out = &reader->IWMReaderAdvanced6_iface; + else if (IsEqualIID(iid, &IID_IWMReaderNetworkConfig) + || IsEqualIID(iid, &IID_IWMReaderNetworkConfig2)) + *out = &reader->IWMReaderNetworkConfig2_iface; + else if (IsEqualIID(iid, &IID_IWMReaderStreamClock)) + *out = &reader->IWMReaderStreamClock_iface; + else if (IsEqualIID(iid, &IID_IWMReaderTypeNegotiation)) + *out = &reader->IWMReaderTypeNegotiation_iface; + else if (IsEqualIID(iid, &IID_IWMHeaderInfo) + || IsEqualIID(iid, &IID_IWMHeaderInfo2) + || IsEqualIID(iid, &IID_IWMHeaderInfo3)) + *out = &reader->reader.IWMHeaderInfo3_iface; + else if (IsEqualIID(iid, &IID_IWMLanguageList)) + *out = &reader->reader.IWMLanguageList_iface; + else if (IsEqualIID(iid, &IID_IWMPacketSize) + || IsEqualIID(iid, &IID_IWMPacketSize2)) + *out = &reader->reader.IWMPacketSize2_iface; + else if (IsEqualIID(iid, &IID_IWMProfile) + || IsEqualIID(iid, &IID_IWMProfile2) + || IsEqualIID(iid, &IID_IWMProfile3)) + *out = &reader->reader.IWMProfile3_iface; + else if (IsEqualIID(iid, &IID_IWMReaderPlaylistBurn)) + *out = &reader->reader.IWMReaderPlaylistBurn_iface; + else if (IsEqualIID(iid, &IID_IWMReaderTimecode)) + *out = &reader->reader.IWMReaderTimecode_iface; + else if (IsEqualIID(iid, &IID_IReferenceClock)) + *out = &reader->IReferenceClock_iface; + else + { + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown *)*out); + return S_OK; }
static ULONG WINAPI WMReader_AddRef(IWMReader *iface) { struct async_reader *reader = impl_from_IWMReader(iface); - - return IWMProfile3_AddRef(&reader->reader.IWMProfile3_iface); + ULONG refcount = InterlockedIncrement(&reader->refcount); + TRACE("%p increasing refcount to %lu.\n", reader, refcount); + return refcount; }
static ULONG WINAPI WMReader_Release(IWMReader *iface) { struct async_reader *reader = impl_from_IWMReader(iface); + ULONG refcount = InterlockedDecrement(&reader->refcount); + + TRACE("%p decreasing refcount to %lu.\n", reader, refcount); + + if (!refcount) + { + EnterCriticalSection(&reader->callback_cs); + reader->running = false; + LeaveCriticalSection(&reader->callback_cs); + WakeConditionVariable(&reader->callback_cv); + + async_reader_close(reader); + + reader->callback_cs.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&reader->callback_cs); + reader->cs.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&reader->cs);
- return IWMProfile3_Release(&reader->reader.IWMProfile3_iface); + wm_reader_close(&reader->reader); + + wm_reader_cleanup(&reader->reader); + free(reader); + } + + return refcount; }
static HRESULT WINAPI WMReader_Open(IWMReader *iface, const WCHAR *url, @@ -551,22 +622,22 @@ static struct async_reader *impl_from_IWMReaderAdvanced6(IWMReaderAdvanced6 *ifa return CONTAINING_RECORD(iface, struct async_reader, IWMReaderAdvanced6_iface); }
-static HRESULT WINAPI WMReaderAdvanced_QueryInterface(IWMReaderAdvanced6 *iface, REFIID riid, void **ppv) +static HRESULT WINAPI WMReaderAdvanced_QueryInterface(IWMReaderAdvanced6 *iface, REFIID iid, void **out) { - struct async_reader *This = impl_from_IWMReaderAdvanced6(iface); - return IWMReader_QueryInterface(&This->IWMReader_iface, riid, ppv); + struct async_reader *reader = impl_from_IWMReaderAdvanced6(iface); + return IUnknown_QueryInterface(reader->reader.outer, iid, out); }
static ULONG WINAPI WMReaderAdvanced_AddRef(IWMReaderAdvanced6 *iface) { - struct async_reader *This = impl_from_IWMReaderAdvanced6(iface); - return IWMReader_AddRef(&This->IWMReader_iface); + struct async_reader *reader = impl_from_IWMReaderAdvanced6(iface); + return IUnknown_AddRef(reader->reader.outer); }
static ULONG WINAPI WMReaderAdvanced_Release(IWMReaderAdvanced6 *iface) { - struct async_reader *This = impl_from_IWMReaderAdvanced6(iface); - return IWMReader_Release(&This->IWMReader_iface); + struct async_reader *reader = impl_from_IWMReaderAdvanced6(iface); + return IUnknown_Release(reader->reader.outer); }
static HRESULT WINAPI WMReaderAdvanced_SetUserProvidedClock(IWMReaderAdvanced6 *iface, BOOL user_clock) @@ -1034,22 +1105,22 @@ static struct async_reader *impl_from_IWMReaderAccelerator(IWMReaderAccelerator return CONTAINING_RECORD(iface, struct async_reader, IWMReaderAccelerator_iface); }
-static HRESULT WINAPI reader_accl_QueryInterface(IWMReaderAccelerator *iface, REFIID riid, void **object) +static HRESULT WINAPI reader_accl_QueryInterface(IWMReaderAccelerator *iface, REFIID iid, void **out) { - struct async_reader *This = impl_from_IWMReaderAccelerator(iface); - return IWMReader_QueryInterface(&This->IWMReader_iface, riid, object); + struct async_reader *reader = impl_from_IWMReaderAccelerator(iface); + return IUnknown_QueryInterface(reader->reader.outer, iid, out); }
static ULONG WINAPI reader_accl_AddRef(IWMReaderAccelerator *iface) { - struct async_reader *This = impl_from_IWMReaderAccelerator(iface); - return IWMReader_AddRef(&This->IWMReader_iface); + struct async_reader *reader = impl_from_IWMReaderAccelerator(iface); + return IUnknown_AddRef(reader->reader.outer); }
static ULONG WINAPI reader_accl_Release(IWMReaderAccelerator *iface) { - struct async_reader *This = impl_from_IWMReaderAccelerator(iface); - return IWMReader_Release(&This->IWMReader_iface); + struct async_reader *reader = impl_from_IWMReaderAccelerator(iface); + return IUnknown_Release(reader->reader.outer); }
static HRESULT WINAPI reader_accl_GetCodecInterface(IWMReaderAccelerator *iface, DWORD output, REFIID riid, void **codec) @@ -1083,22 +1154,22 @@ static struct async_reader *impl_from_IWMReaderNetworkConfig2(IWMReaderNetworkCo return CONTAINING_RECORD(iface, struct async_reader, IWMReaderNetworkConfig2_iface); }
-static HRESULT WINAPI networkconfig_QueryInterface(IWMReaderNetworkConfig2 *iface, REFIID riid, void **ppv) +static HRESULT WINAPI networkconfig_QueryInterface(IWMReaderNetworkConfig2 *iface, REFIID iid, void **out) { - struct async_reader *This = impl_from_IWMReaderNetworkConfig2(iface); - return IWMReader_QueryInterface(&This->IWMReader_iface, riid, ppv); + struct async_reader *reader = impl_from_IWMReaderNetworkConfig2(iface); + return IUnknown_QueryInterface(reader->reader.outer, iid, out); }
static ULONG WINAPI networkconfig_AddRef(IWMReaderNetworkConfig2 *iface) { - struct async_reader *This = impl_from_IWMReaderNetworkConfig2(iface); - return IWMReader_AddRef(&This->IWMReader_iface); + struct async_reader *reader = impl_from_IWMReaderNetworkConfig2(iface); + return IUnknown_AddRef(reader->reader.outer); }
static ULONG WINAPI networkconfig_Release(IWMReaderNetworkConfig2 *iface) { - struct async_reader *This = impl_from_IWMReaderNetworkConfig2(iface); - return IWMReader_Release(&This->IWMReader_iface); + struct async_reader *reader = impl_from_IWMReaderNetworkConfig2(iface); + return IUnknown_Release(reader->reader.outer); }
static HRESULT WINAPI networkconfig_GetBufferingTime(IWMReaderNetworkConfig2 *iface, QWORD *buffering_time) @@ -1511,22 +1582,22 @@ static struct async_reader *impl_from_IWMReaderStreamClock(IWMReaderStreamClock return CONTAINING_RECORD(iface, struct async_reader, IWMReaderStreamClock_iface); }
-static HRESULT WINAPI readclock_QueryInterface(IWMReaderStreamClock *iface, REFIID riid, void **ppv) +static HRESULT WINAPI readclock_QueryInterface(IWMReaderStreamClock *iface, REFIID iid, void **out) { - struct async_reader *This = impl_from_IWMReaderStreamClock(iface); - return IWMReader_QueryInterface(&This->IWMReader_iface, riid, ppv); + struct async_reader *reader = impl_from_IWMReaderStreamClock(iface); + return IUnknown_QueryInterface(reader->reader.outer, iid, out); }
static ULONG WINAPI readclock_AddRef(IWMReaderStreamClock *iface) { - struct async_reader *This = impl_from_IWMReaderStreamClock(iface); - return IWMReader_AddRef(&This->IWMReader_iface); + struct async_reader *reader = impl_from_IWMReaderStreamClock(iface); + return IUnknown_AddRef(reader->reader.outer); }
static ULONG WINAPI readclock_Release(IWMReaderStreamClock *iface) { - struct async_reader *This = impl_from_IWMReaderStreamClock(iface); - return IWMReader_Release(&This->IWMReader_iface); + struct async_reader *reader = impl_from_IWMReaderStreamClock(iface); + return IUnknown_Release(reader->reader.outer); }
static HRESULT WINAPI readclock_GetTime(IWMReaderStreamClock *iface, QWORD *now) @@ -1567,22 +1638,22 @@ static struct async_reader *impl_from_IWMReaderTypeNegotiation(IWMReaderTypeNego return CONTAINING_RECORD(iface, struct async_reader, IWMReaderTypeNegotiation_iface); }
-static HRESULT WINAPI negotiation_QueryInterface(IWMReaderTypeNegotiation *iface, REFIID riid, void **ppv) +static HRESULT WINAPI negotiation_QueryInterface(IWMReaderTypeNegotiation *iface, REFIID iid, void **out) { - struct async_reader *This = impl_from_IWMReaderTypeNegotiation(iface); - return IWMReader_QueryInterface(&This->IWMReader_iface, riid, ppv); + struct async_reader *reader = impl_from_IWMReaderTypeNegotiation(iface); + return IUnknown_QueryInterface(reader->reader.outer, iid, out); }
static ULONG WINAPI negotiation_AddRef(IWMReaderTypeNegotiation *iface) { - struct async_reader *This = impl_from_IWMReaderTypeNegotiation(iface); - return IWMReader_AddRef(&This->IWMReader_iface); + struct async_reader *reader = impl_from_IWMReaderTypeNegotiation(iface); + return IUnknown_AddRef(reader->reader.outer); }
static ULONG WINAPI negotiation_Release(IWMReaderTypeNegotiation *iface) { - struct async_reader *This = impl_from_IWMReaderTypeNegotiation(iface); - return IWMReader_Release(&This->IWMReader_iface); + struct async_reader *reader = impl_from_IWMReaderTypeNegotiation(iface); + return IUnknown_Release(reader->reader.outer); }
static HRESULT WINAPI negotiation_TryOutputProps(IWMReaderTypeNegotiation *iface, DWORD output, IWMOutputMediaProps *props) @@ -1607,22 +1678,22 @@ static struct async_reader *impl_from_IReferenceClock(IReferenceClock *iface) return CONTAINING_RECORD(iface, struct async_reader, IReferenceClock_iface); }
-static HRESULT WINAPI refclock_QueryInterface(IReferenceClock *iface, REFIID riid, void **ppv) +static HRESULT WINAPI refclock_QueryInterface(IReferenceClock *iface, REFIID iid, void **out) { - struct async_reader *This = impl_from_IReferenceClock(iface); - return IWMReader_QueryInterface(&This->IWMReader_iface, riid, ppv); + struct async_reader *reader = impl_from_IReferenceClock(iface); + return IUnknown_QueryInterface(reader->reader.outer, iid, out); }
static ULONG WINAPI refclock_AddRef(IReferenceClock *iface) { - struct async_reader *This = impl_from_IReferenceClock(iface); - return IWMReader_AddRef(&This->IWMReader_iface); + struct async_reader *reader = impl_from_IReferenceClock(iface); + return IUnknown_AddRef(reader->reader.outer); }
static ULONG WINAPI refclock_Release(IReferenceClock *iface) { - struct async_reader *This = impl_from_IReferenceClock(iface); - return IWMReader_Release(&This->IWMReader_iface); + struct async_reader *reader = impl_from_IReferenceClock(iface); + return IUnknown_Release(reader->reader.outer); }
static HRESULT WINAPI refclock_GetTime(IReferenceClock *iface, REFERENCE_TIME *time) @@ -1674,77 +1745,6 @@ static const IReferenceClockVtbl ReferenceClockVtbl = refclock_Unadvise };
-static struct async_reader *impl_from_wm_reader(struct wm_reader *iface) -{ - return CONTAINING_RECORD(iface, struct async_reader, reader); -} - -static void *async_reader_query_interface(struct wm_reader *iface, REFIID iid) -{ - struct async_reader *reader = impl_from_wm_reader(iface); - - TRACE("reader %p, iid %s.\n", reader, debugstr_guid(iid)); - - if (IsEqualIID(iid, &IID_IReferenceClock)) - return &reader->IReferenceClock_iface; - - if (IsEqualIID(iid, &IID_IWMReader)) - return &reader->IWMReader_iface; - - if (IsEqualIID(iid, &IID_IWMReaderAccelerator)) - return &reader->IWMReaderAccelerator_iface; - - if (IsEqualIID(iid, &IID_IWMReaderAdvanced) - || IsEqualIID(iid, &IID_IWMReaderAdvanced2) - || IsEqualIID(iid, &IID_IWMReaderAdvanced3) - || IsEqualIID(iid, &IID_IWMReaderAdvanced4) - || IsEqualIID(iid, &IID_IWMReaderAdvanced5) - || IsEqualIID(iid, &IID_IWMReaderAdvanced6)) - return &reader->IWMReaderAdvanced6_iface; - - if (IsEqualIID(iid, &IID_IWMReaderNetworkConfig) - || IsEqualIID(iid, &IID_IWMReaderNetworkConfig2)) - return &reader->IWMReaderNetworkConfig2_iface; - - if (IsEqualIID(iid, &IID_IWMReaderStreamClock)) - return &reader->IWMReaderStreamClock_iface; - - if (IsEqualIID(iid, &IID_IWMReaderTypeNegotiation)) - return &reader->IWMReaderTypeNegotiation_iface; - - return NULL; -} - -static void async_reader_destroy(struct wm_reader *iface) -{ - struct async_reader *reader = impl_from_wm_reader(iface); - - TRACE("reader %p.\n", reader); - - EnterCriticalSection(&reader->callback_cs); - reader->running = false; - LeaveCriticalSection(&reader->callback_cs); - WakeConditionVariable(&reader->callback_cv); - - async_reader_close(reader); - - reader->callback_cs.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&reader->callback_cs); - reader->cs.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&reader->cs); - - wm_reader_close(&reader->reader); - - wm_reader_cleanup(&reader->reader); - free(reader); -} - -static const struct wm_reader_ops async_reader_ops = -{ - .query_interface = async_reader_query_interface, - .destroy = async_reader_destroy, -}; - HRESULT WINAPI winegstreamer_create_wm_async_reader(IWMReader **reader) { struct async_reader *object; @@ -1754,8 +1754,6 @@ HRESULT WINAPI winegstreamer_create_wm_async_reader(IWMReader **reader) if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY;
- wm_reader_init(&object->reader, &async_reader_ops); - object->IReferenceClock_iface.lpVtbl = &ReferenceClockVtbl; object->IWMReader_iface.lpVtbl = &WMReaderVtbl; object->IWMReaderAdvanced6_iface.lpVtbl = &WMReaderAdvanced6Vtbl; @@ -1763,6 +1761,8 @@ HRESULT WINAPI winegstreamer_create_wm_async_reader(IWMReader **reader) object->IWMReaderNetworkConfig2_iface.lpVtbl = &WMReaderNetworkConfig2Vtbl; object->IWMReaderStreamClock_iface.lpVtbl = &WMReaderStreamClockVtbl; object->IWMReaderTypeNegotiation_iface.lpVtbl = &WMReaderTypeNegotiationVtbl; + wm_reader_init((IUnknown *)&object->IWMReader_iface, &object->reader); + object->refcount = 1;
InitializeCriticalSection(&object->cs); object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": async_reader.cs"); diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c index 243ebb20335..5d7a209bfc9 100644 --- a/dlls/winegstreamer/wm_reader.c +++ b/dlls/winegstreamer/wm_reader.c @@ -636,70 +636,19 @@ static struct wm_reader *impl_from_IWMProfile3(IWMProfile3 *iface) static HRESULT WINAPI profile_QueryInterface(IWMProfile3 *iface, REFIID iid, void **out) { struct wm_reader *reader = impl_from_IWMProfile3(iface); - - TRACE("reader %p, iid %s, out %p.\n", reader, debugstr_guid(iid), out); - - if (IsEqualIID(iid, &IID_IWMHeaderInfo) - || IsEqualIID(iid, &IID_IWMHeaderInfo2) - || IsEqualIID(iid, &IID_IWMHeaderInfo3)) - { - *out = &reader->IWMHeaderInfo3_iface; - } - else if (IsEqualIID(iid, &IID_IWMLanguageList)) - { - *out = &reader->IWMLanguageList_iface; - } - else if (IsEqualIID(iid, &IID_IWMPacketSize) - || IsEqualIID(iid, &IID_IWMPacketSize2)) - { - *out = &reader->IWMPacketSize2_iface; - } - else if (IsEqualIID(iid, &IID_IUnknown) - || IsEqualIID(iid, &IID_IWMProfile) - || IsEqualIID(iid, &IID_IWMProfile2) - || IsEqualIID(iid, &IID_IWMProfile3)) - { - *out = &reader->IWMProfile3_iface; - } - else if (IsEqualIID(iid, &IID_IWMReaderPlaylistBurn)) - { - *out = &reader->IWMReaderPlaylistBurn_iface; - } - else if (IsEqualIID(iid, &IID_IWMReaderTimecode)) - { - *out = &reader->IWMReaderTimecode_iface; - } - else if (!(*out = reader->ops->query_interface(reader, iid))) - { - WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown *)*out); - return S_OK; + return IUnknown_QueryInterface(reader->outer, iid, out); }
static ULONG WINAPI profile_AddRef(IWMProfile3 *iface) { struct wm_reader *reader = impl_from_IWMProfile3(iface); - ULONG refcount = InterlockedIncrement(&reader->refcount); - - TRACE("%p increasing refcount to %lu.\n", reader, refcount); - - return refcount; + return IUnknown_AddRef(reader->outer); }
static ULONG WINAPI profile_Release(IWMProfile3 *iface) { struct wm_reader *reader = impl_from_IWMProfile3(iface); - ULONG refcount = InterlockedDecrement(&reader->refcount); - - TRACE("%p decreasing refcount to %lu.\n", reader, refcount); - - if (!refcount) - reader->ops->destroy(reader); - - return refcount; + return IUnknown_Release(reader->outer); }
static HRESULT WINAPI profile_GetVersion(IWMProfile3 *iface, WMT_VERSION *version) @@ -972,22 +921,19 @@ static struct wm_reader *impl_from_IWMHeaderInfo3(IWMHeaderInfo3 *iface) static HRESULT WINAPI header_info_QueryInterface(IWMHeaderInfo3 *iface, REFIID iid, void **out) { struct wm_reader *reader = impl_from_IWMHeaderInfo3(iface); - - return IWMProfile3_QueryInterface(&reader->IWMProfile3_iface, iid, out); + return IUnknown_QueryInterface(reader->outer, iid, out); }
static ULONG WINAPI header_info_AddRef(IWMHeaderInfo3 *iface) { struct wm_reader *reader = impl_from_IWMHeaderInfo3(iface); - - return IWMProfile3_AddRef(&reader->IWMProfile3_iface); + return IUnknown_AddRef(reader->outer); }
static ULONG WINAPI header_info_Release(IWMHeaderInfo3 *iface) { struct wm_reader *reader = impl_from_IWMHeaderInfo3(iface); - - return IWMProfile3_Release(&reader->IWMProfile3_iface); + return IUnknown_Release(reader->outer); }
static HRESULT WINAPI header_info_GetAttributeCount(IWMHeaderInfo3 *iface, WORD stream_number, WORD *count) @@ -1237,22 +1183,19 @@ static struct wm_reader *impl_from_IWMLanguageList(IWMLanguageList *iface) static HRESULT WINAPI language_list_QueryInterface(IWMLanguageList *iface, REFIID iid, void **out) { struct wm_reader *reader = impl_from_IWMLanguageList(iface); - - return IWMProfile3_QueryInterface(&reader->IWMProfile3_iface, iid, out); + return IUnknown_QueryInterface(reader->outer, iid, out); }
static ULONG WINAPI language_list_AddRef(IWMLanguageList *iface) { struct wm_reader *reader = impl_from_IWMLanguageList(iface); - - return IWMProfile3_AddRef(&reader->IWMProfile3_iface); + return IUnknown_AddRef(reader->outer); }
static ULONG WINAPI language_list_Release(IWMLanguageList *iface) { struct wm_reader *reader = impl_from_IWMLanguageList(iface); - - return IWMProfile3_Release(&reader->IWMProfile3_iface); + return IUnknown_Release(reader->outer); }
static HRESULT WINAPI language_list_GetLanguageCount(IWMLanguageList *iface, WORD *count) @@ -1293,22 +1236,19 @@ static struct wm_reader *impl_from_IWMPacketSize2(IWMPacketSize2 *iface) static HRESULT WINAPI packet_size_QueryInterface(IWMPacketSize2 *iface, REFIID iid, void **out) { struct wm_reader *reader = impl_from_IWMPacketSize2(iface); - - return IWMProfile3_QueryInterface(&reader->IWMProfile3_iface, iid, out); + return IUnknown_QueryInterface(reader->outer, iid, out); }
static ULONG WINAPI packet_size_AddRef(IWMPacketSize2 *iface) { struct wm_reader *reader = impl_from_IWMPacketSize2(iface); - - return IWMProfile3_AddRef(&reader->IWMProfile3_iface); + return IUnknown_AddRef(reader->outer); }
static ULONG WINAPI packet_size_Release(IWMPacketSize2 *iface) { struct wm_reader *reader = impl_from_IWMPacketSize2(iface); - - return IWMProfile3_Release(&reader->IWMProfile3_iface); + return IUnknown_Release(reader->outer); }
static HRESULT WINAPI packet_size_GetMaxPacketSize(IWMPacketSize2 *iface, DWORD *size) @@ -1354,22 +1294,19 @@ static struct wm_reader *impl_from_IWMReaderPlaylistBurn(IWMReaderPlaylistBurn * static HRESULT WINAPI playlist_QueryInterface(IWMReaderPlaylistBurn *iface, REFIID iid, void **out) { struct wm_reader *reader = impl_from_IWMReaderPlaylistBurn(iface); - - return IWMProfile3_QueryInterface(&reader->IWMProfile3_iface, iid, out); + return IUnknown_QueryInterface(reader->outer, iid, out); }
static ULONG WINAPI playlist_AddRef(IWMReaderPlaylistBurn *iface) { struct wm_reader *reader = impl_from_IWMReaderPlaylistBurn(iface); - - return IWMProfile3_AddRef(&reader->IWMProfile3_iface); + return IUnknown_AddRef(reader->outer); }
static ULONG WINAPI playlist_Release(IWMReaderPlaylistBurn *iface) { struct wm_reader *reader = impl_from_IWMReaderPlaylistBurn(iface); - - return IWMProfile3_Release(&reader->IWMProfile3_iface); + return IUnknown_Release(reader->outer); }
static HRESULT WINAPI playlist_InitPlaylistBurn(IWMReaderPlaylistBurn *iface, DWORD count, @@ -1417,22 +1354,19 @@ static struct wm_reader *impl_from_IWMReaderTimecode(IWMReaderTimecode *iface) static HRESULT WINAPI timecode_QueryInterface(IWMReaderTimecode *iface, REFIID iid, void **out) { struct wm_reader *reader = impl_from_IWMReaderTimecode(iface); - - return IWMProfile3_QueryInterface(&reader->IWMProfile3_iface, iid, out); + return IUnknown_QueryInterface(reader->outer, iid, out); }
static ULONG WINAPI timecode_AddRef(IWMReaderTimecode *iface) { struct wm_reader *reader = impl_from_IWMReaderTimecode(iface); - - return IWMProfile3_AddRef(&reader->IWMProfile3_iface); + return IUnknown_AddRef(reader->outer); }
static ULONG WINAPI timecode_Release(IWMReaderTimecode *iface) { struct wm_reader *reader = impl_from_IWMReaderTimecode(iface); - - return IWMProfile3_Release(&reader->IWMProfile3_iface); + return IUnknown_Release(reader->outer); }
static HRESULT WINAPI timecode_GetTimecodeRangeCount(IWMReaderTimecode *iface, @@ -2205,7 +2139,7 @@ HRESULT wm_reader_get_max_stream_size(struct wm_reader *reader, WORD stream_numb return S_OK; }
-void wm_reader_init(struct wm_reader *reader, const struct wm_reader_ops *ops) +void wm_reader_init(IUnknown *outer, struct wm_reader *reader) { reader->IWMHeaderInfo3_iface.lpVtbl = &header_info_vtbl; reader->IWMLanguageList_iface.lpVtbl = &language_list_vtbl; @@ -2213,8 +2147,7 @@ void wm_reader_init(struct wm_reader *reader, const struct wm_reader_ops *ops) reader->IWMProfile3_iface.lpVtbl = &profile_vtbl; reader->IWMReaderPlaylistBurn_iface.lpVtbl = &playlist_vtbl; reader->IWMReaderTimecode_iface.lpVtbl = &timecode_vtbl; - reader->refcount = 1; - reader->ops = ops; + reader->outer = outer;
InitializeCriticalSection(&reader->cs); reader->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": wm_reader.cs"); diff --git a/dlls/winegstreamer/wm_syncreader.c b/dlls/winegstreamer/wm_syncreader.c index c80574b87fd..814d38cc089 100644 --- a/dlls/winegstreamer/wm_syncreader.c +++ b/dlls/winegstreamer/wm_syncreader.c @@ -22,9 +22,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(wmvcore);
struct sync_reader { - struct wm_reader reader; - IWMSyncReader2 IWMSyncReader2_iface; + struct wm_reader reader; + LONG refcount; };
static struct sync_reader *impl_from_IWMSyncReader2(IWMSyncReader2 *iface) @@ -36,21 +36,62 @@ static HRESULT WINAPI WMSyncReader_QueryInterface(IWMSyncReader2 *iface, REFIID { struct sync_reader *reader = impl_from_IWMSyncReader2(iface);
- return IWMProfile3_QueryInterface(&reader->reader.IWMProfile3_iface, iid, out); + TRACE("reader %p, iid %s, out %p.\n", reader, debugstr_guid(iid), out); + + if (IsEqualIID(iid, &IID_IUnknown) + || IsEqualIID(iid, &IID_IWMSyncReader) + || IsEqualIID(iid, &IID_IWMSyncReader2)) + *out = &reader->IWMSyncReader2_iface; + else if (IsEqualIID(iid, &IID_IWMHeaderInfo) + || IsEqualIID(iid, &IID_IWMHeaderInfo2) + || IsEqualIID(iid, &IID_IWMHeaderInfo3)) + *out = &reader->reader.IWMHeaderInfo3_iface; + else if (IsEqualIID(iid, &IID_IWMLanguageList)) + *out = &reader->reader.IWMLanguageList_iface; + else if (IsEqualIID(iid, &IID_IWMPacketSize) + || IsEqualIID(iid, &IID_IWMPacketSize2)) + *out = &reader->reader.IWMPacketSize2_iface; + else if (IsEqualIID(iid, &IID_IWMProfile) + || IsEqualIID(iid, &IID_IWMProfile2) + || IsEqualIID(iid, &IID_IWMProfile3)) + *out = &reader->reader.IWMProfile3_iface; + else if (IsEqualIID(iid, &IID_IWMReaderPlaylistBurn)) + *out = &reader->reader.IWMReaderPlaylistBurn_iface; + else if (IsEqualIID(iid, &IID_IWMReaderTimecode)) + *out = &reader->reader.IWMReaderTimecode_iface; + else + { + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown *)*out); + return S_OK; }
static ULONG WINAPI WMSyncReader_AddRef(IWMSyncReader2 *iface) { struct sync_reader *reader = impl_from_IWMSyncReader2(iface); - - return IWMProfile3_AddRef(&reader->reader.IWMProfile3_iface); + ULONG refcount = InterlockedIncrement(&reader->refcount); + TRACE("%p increasing refcount to %lu.\n", reader, refcount); + return refcount; }
static ULONG WINAPI WMSyncReader_Release(IWMSyncReader2 *iface) { struct sync_reader *reader = impl_from_IWMSyncReader2(iface); + ULONG refcount = InterlockedDecrement(&reader->refcount); + + TRACE("%p decreasing refcount to %lu.\n", reader, refcount);
- return IWMProfile3_Release(&reader->reader.IWMProfile3_iface); + if (!refcount) + { + wm_reader_close(&reader->reader); + wm_reader_cleanup(&reader->reader); + free(reader); + } + + return refcount; }
static HRESULT WINAPI WMSyncReader_Close(IWMSyncReader2 *iface) @@ -363,41 +404,6 @@ static const IWMSyncReader2Vtbl WMSyncReader2Vtbl = { WMSyncReader2_GetAllocateForStream };
-static struct sync_reader *impl_from_wm_reader(struct wm_reader *iface) -{ - return CONTAINING_RECORD(iface, struct sync_reader, reader); -} - -static void *sync_reader_query_interface(struct wm_reader *iface, REFIID iid) -{ - struct sync_reader *reader = impl_from_wm_reader(iface); - - TRACE("reader %p, iid %s.\n", reader, debugstr_guid(iid)); - - if (IsEqualIID(iid, &IID_IWMSyncReader) - || IsEqualIID(iid, &IID_IWMSyncReader2)) - return &reader->IWMSyncReader2_iface; - - return NULL; -} - -static void sync_reader_destroy(struct wm_reader *iface) -{ - struct sync_reader *reader = impl_from_wm_reader(iface); - - TRACE("reader %p.\n", reader); - - wm_reader_close(&reader->reader); - wm_reader_cleanup(&reader->reader); - free(reader); -} - -static const struct wm_reader_ops sync_reader_ops = -{ - .query_interface = sync_reader_query_interface, - .destroy = sync_reader_destroy, -}; - HRESULT WINAPI winegstreamer_create_wm_sync_reader(IWMSyncReader **reader) { struct sync_reader *object; @@ -407,9 +413,9 @@ HRESULT WINAPI winegstreamer_create_wm_sync_reader(IWMSyncReader **reader) if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY;
- wm_reader_init(&object->reader, &sync_reader_ops); - object->IWMSyncReader2_iface.lpVtbl = &WMSyncReader2Vtbl; + wm_reader_init((IUnknown *)&object->IWMSyncReader2_iface, &object->reader); + object->refcount = 1;
TRACE("Created sync reader %p.\n", object); *reader = (IWMSyncReader *)&object->IWMSyncReader2_iface;
From: Rémi Bernon rbernon@codeweavers.com
Instead of an internal struct wm_reader. --- dlls/winegstreamer/gst_private.h | 3 + dlls/winegstreamer/winegstreamer.spec | 2 +- dlls/winegstreamer/wm_asyncreader.c | 122 ++++++++++++++------------ dlls/winegstreamer/wm_syncreader.c | 62 ++++++++++--- dlls/wmvcore/wmvcore_main.c | 6 +- 5 files changed, 122 insertions(+), 73 deletions(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index f60892e00f1..f916fde8318 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -183,6 +183,9 @@ struct wm_reader WORD stream_count; };
+HRESULT WINAPI winegstreamer_create_wm_sync_reader(IUnknown *outer, void **out); +struct wm_reader *wm_reader_from_sync_reader_inner(IUnknown *inner); + void wm_reader_cleanup(struct wm_reader *reader); HRESULT wm_reader_close(struct wm_reader *reader); HRESULT wm_reader_get_max_stream_size(struct wm_reader *reader, WORD stream_number, DWORD *size); diff --git a/dlls/winegstreamer/winegstreamer.spec b/dlls/winegstreamer/winegstreamer.spec index bc6a390f8b1..911689210b7 100644 --- a/dlls/winegstreamer/winegstreamer.spec +++ b/dlls/winegstreamer/winegstreamer.spec @@ -3,4 +3,4 @@ @ stdcall -private DllRegisterServer() @ stdcall -private DllUnregisterServer() @ stdcall winegstreamer_create_wm_async_reader(ptr) -@ stdcall winegstreamer_create_wm_sync_reader(ptr) +@ stdcall winegstreamer_create_wm_sync_reader(ptr ptr) diff --git a/dlls/winegstreamer/wm_asyncreader.c b/dlls/winegstreamer/wm_asyncreader.c index c9d134d5245..e74e25228b6 100644 --- a/dlls/winegstreamer/wm_asyncreader.c +++ b/dlls/winegstreamer/wm_asyncreader.c @@ -61,9 +61,11 @@ struct async_reader IWMReaderStreamClock IWMReaderStreamClock_iface; IWMReaderTypeNegotiation IWMReaderTypeNegotiation_iface; IReferenceClock IReferenceClock_iface; - struct wm_reader reader; + IUnknown *reader_inner; LONG refcount;
+ struct wm_reader *wm_reader; + CRITICAL_SECTION cs;
IWMReaderCallbackAdvanced *callback_advanced; @@ -143,7 +145,7 @@ static void async_reader_deliver_sample(struct async_reader *reader, struct samp reader, sample->stream, debugstr_time(sample->pts), debugstr_time(sample->duration), sample->flags, sample->buffer);
- stream = wm_reader_get_stream_by_stream_number(&reader->reader, sample->stream); + stream = wm_reader_get_stream_by_stream_number(reader->wm_reader, sample->stream); read_compressed = stream->read_compressed;
LeaveCriticalSection(&reader->callback_cs); @@ -172,7 +174,7 @@ static void callback_thread_run(struct async_reader *reader) struct sample sample;
LeaveCriticalSection(&reader->callback_cs); - hr = wm_reader_get_stream_sample(&reader->reader, callback_advanced, 0, &sample.buffer, + hr = wm_reader_get_stream_sample(reader->wm_reader, callback_advanced, 0, &sample.buffer, &sample.pts, &sample.duration, &sample.flags, &sample.stream); EnterCriticalSection(&reader->callback_cs); if (hr != S_OK) @@ -242,7 +244,7 @@ static DWORD WINAPI async_reader_callback_thread(void *arg) reader->context = op->u.start.context; if (SUCCEEDED(hr)) { - wm_reader_seek(&reader->reader, op->u.start.start, op->u.start.duration); + wm_reader_seek(reader->wm_reader, op->u.start.start, op->u.start.duration); reader->clock_start = get_current_time(reader); }
@@ -389,21 +391,16 @@ static HRESULT WINAPI WMReader_QueryInterface(IWMReader *iface, REFIID iid, void *out = &reader->IWMReaderTypeNegotiation_iface; else if (IsEqualIID(iid, &IID_IWMHeaderInfo) || IsEqualIID(iid, &IID_IWMHeaderInfo2) - || IsEqualIID(iid, &IID_IWMHeaderInfo3)) - *out = &reader->reader.IWMHeaderInfo3_iface; - else if (IsEqualIID(iid, &IID_IWMLanguageList)) - *out = &reader->reader.IWMLanguageList_iface; - else if (IsEqualIID(iid, &IID_IWMPacketSize) - || IsEqualIID(iid, &IID_IWMPacketSize2)) - *out = &reader->reader.IWMPacketSize2_iface; - else if (IsEqualIID(iid, &IID_IWMProfile) + || IsEqualIID(iid, &IID_IWMHeaderInfo3) + || IsEqualIID(iid, &IID_IWMLanguageList) + || IsEqualIID(iid, &IID_IWMPacketSize) + || IsEqualIID(iid, &IID_IWMPacketSize2) + || IsEqualIID(iid, &IID_IWMProfile) || IsEqualIID(iid, &IID_IWMProfile2) - || IsEqualIID(iid, &IID_IWMProfile3)) - *out = &reader->reader.IWMProfile3_iface; - else if (IsEqualIID(iid, &IID_IWMReaderPlaylistBurn)) - *out = &reader->reader.IWMReaderPlaylistBurn_iface; - else if (IsEqualIID(iid, &IID_IWMReaderTimecode)) - *out = &reader->reader.IWMReaderTimecode_iface; + || IsEqualIID(iid, &IID_IWMProfile3) + || IsEqualIID(iid, &IID_IWMReaderPlaylistBurn) + || IsEqualIID(iid, &IID_IWMReaderTimecode)) + return IUnknown_QueryInterface(reader->reader_inner, iid, out); else if (IsEqualIID(iid, &IID_IReferenceClock)) *out = &reader->IReferenceClock_iface; else @@ -445,9 +442,9 @@ static ULONG WINAPI WMReader_Release(IWMReader *iface) reader->cs.DebugInfo->Spare[0] = 0; DeleteCriticalSection(&reader->cs);
- wm_reader_close(&reader->reader); + wm_reader_close(reader->wm_reader);
- wm_reader_cleanup(&reader->reader); + IUnknown_Release(reader->reader_inner); free(reader); }
@@ -465,9 +462,9 @@ static HRESULT WINAPI WMReader_Open(IWMReader *iface, const WCHAR *url,
EnterCriticalSection(&reader->cs);
- if (SUCCEEDED(hr = wm_reader_open_file(&reader->reader, url)) + if (SUCCEEDED(hr = wm_reader_open_file(reader->wm_reader, url)) && FAILED(hr = async_reader_open(reader, callback, context))) - wm_reader_close(&reader->reader); + wm_reader_close(reader->wm_reader);
LeaveCriticalSection(&reader->cs); return hr; @@ -485,7 +482,7 @@ static HRESULT WINAPI WMReader_Close(IWMReader *iface) if (SUCCEEDED(hr = async_reader_queue_op(reader, ASYNC_OP_CLOSE, NULL))) { async_reader_close(reader); - hr = wm_reader_close(&reader->reader); + hr = wm_reader_close(reader->wm_reader); }
LeaveCriticalSection(&reader->cs); @@ -499,9 +496,9 @@ static HRESULT WINAPI WMReader_GetOutputCount(IWMReader *iface, DWORD *count)
TRACE("reader %p, count %p.\n", reader, count);
- EnterCriticalSection(&reader->reader.cs); - *count = reader->reader.stream_count; - LeaveCriticalSection(&reader->reader.cs); + EnterCriticalSection(&reader->wm_reader->cs); + *count = reader->wm_reader->stream_count; + LeaveCriticalSection(&reader->wm_reader->cs); return S_OK; }
@@ -511,7 +508,7 @@ static HRESULT WINAPI WMReader_GetOutputProps(IWMReader *iface, DWORD output, IW
TRACE("reader %p, output %lu, props %p.\n", reader, output, props);
- return wm_reader_get_output_props(&reader->reader, output, props); + return wm_reader_get_output_props(reader->wm_reader, output, props); }
static HRESULT WINAPI WMReader_SetOutputProps(IWMReader *iface, DWORD output, IWMOutputMediaProps *props) @@ -520,7 +517,7 @@ static HRESULT WINAPI WMReader_SetOutputProps(IWMReader *iface, DWORD output, IW
TRACE("reader %p, output %lu, props %p.\n", reader, output, props);
- return wm_reader_set_output_props(&reader->reader, output, props); + return wm_reader_set_output_props(reader->wm_reader, output, props); }
static HRESULT WINAPI WMReader_GetOutputFormatCount(IWMReader *iface, DWORD output, DWORD *count) @@ -529,7 +526,7 @@ static HRESULT WINAPI WMReader_GetOutputFormatCount(IWMReader *iface, DWORD outp
TRACE("reader %p, output %lu, count %p.\n", reader, output, count);
- return wm_reader_get_output_format_count(&reader->reader, output, count); + return wm_reader_get_output_format_count(reader->wm_reader, output, count); }
static HRESULT WINAPI WMReader_GetOutputFormat(IWMReader *iface, DWORD output, @@ -539,7 +536,7 @@ static HRESULT WINAPI WMReader_GetOutputFormat(IWMReader *iface, DWORD output,
TRACE("reader %p, output %lu, index %lu, props %p.\n", reader, output, index, props);
- return wm_reader_get_output_format(&reader->reader, output, index, props); + return wm_reader_get_output_format(reader->wm_reader, output, index, props); }
static HRESULT WINAPI WMReader_Start(IWMReader *iface, @@ -625,19 +622,19 @@ static struct async_reader *impl_from_IWMReaderAdvanced6(IWMReaderAdvanced6 *ifa static HRESULT WINAPI WMReaderAdvanced_QueryInterface(IWMReaderAdvanced6 *iface, REFIID iid, void **out) { struct async_reader *reader = impl_from_IWMReaderAdvanced6(iface); - return IUnknown_QueryInterface(reader->reader.outer, iid, out); + return IWMReader_QueryInterface(&reader->IWMReader_iface, iid, out); }
static ULONG WINAPI WMReaderAdvanced_AddRef(IWMReaderAdvanced6 *iface) { struct async_reader *reader = impl_from_IWMReaderAdvanced6(iface); - return IUnknown_AddRef(reader->reader.outer); + return IWMReader_AddRef(&reader->IWMReader_iface); }
static ULONG WINAPI WMReaderAdvanced_Release(IWMReaderAdvanced6 *iface) { struct async_reader *reader = impl_from_IWMReaderAdvanced6(iface); - return IUnknown_Release(reader->reader.outer); + return IWMReader_Release(&reader->IWMReader_iface); }
static HRESULT WINAPI WMReaderAdvanced_SetUserProvidedClock(IWMReaderAdvanced6 *iface, BOOL user_clock) @@ -704,7 +701,7 @@ static HRESULT WINAPI WMReaderAdvanced_SetStreamsSelected(IWMReaderAdvanced6 *if TRACE("reader %p, count %u, stream_numbers %p, selections %p.\n", reader, count, stream_numbers, selections);
- return wm_reader_set_streams_selected(&reader->reader, count, stream_numbers, selections); + return wm_reader_set_streams_selected(reader->wm_reader, count, stream_numbers, selections); }
static HRESULT WINAPI WMReaderAdvanced_GetStreamSelected(IWMReaderAdvanced6 *iface, @@ -714,7 +711,7 @@ static HRESULT WINAPI WMReaderAdvanced_GetStreamSelected(IWMReaderAdvanced6 *ifa
TRACE("reader %p, stream_number %u, selection %p.\n", reader, stream_number, selection);
- return wm_reader_get_stream_selection(&reader->reader, stream_number, selection); + return wm_reader_get_stream_selection(reader->wm_reader, stream_number, selection); }
static HRESULT WINAPI WMReaderAdvanced_SetReceiveSelectionCallbacks(IWMReaderAdvanced6 *iface, BOOL get_callbacks) @@ -738,7 +735,7 @@ static HRESULT WINAPI WMReaderAdvanced_SetReceiveStreamSamples(IWMReaderAdvanced
TRACE("reader %p, stream_number %u, compressed %d.\n", reader, stream_number, compressed);
- return wm_reader_set_read_compressed(&reader->reader, stream_number, compressed); + return wm_reader_set_read_compressed(reader->wm_reader, stream_number, compressed); }
static HRESULT WINAPI WMReaderAdvanced_GetReceiveStreamSamples(IWMReaderAdvanced6 *iface, WORD stream_num, @@ -756,7 +753,7 @@ static HRESULT WINAPI WMReaderAdvanced_SetAllocateForOutput(IWMReaderAdvanced6 *
TRACE("reader %p, output %lu, allocate %d.\n", reader, output, allocate);
- return wm_reader_set_allocate_for_output(&reader->reader, output, allocate); + return wm_reader_set_allocate_for_output(reader->wm_reader, output, allocate); }
static HRESULT WINAPI WMReaderAdvanced_GetAllocateForOutput(IWMReaderAdvanced6 *iface, DWORD output_num, BOOL *allocate) @@ -775,7 +772,7 @@ static HRESULT WINAPI WMReaderAdvanced_SetAllocateForStream(IWMReaderAdvanced6 *
TRACE("reader %p, stream_number %u, allocate %d.\n", reader, stream_number, allocate);
- return wm_reader_set_allocate_for_stream(&reader->reader, stream_number, allocate); + return wm_reader_set_allocate_for_stream(reader->wm_reader, stream_number, allocate); }
static HRESULT WINAPI WMReaderAdvanced_GetAllocateForStream(IWMReaderAdvanced6 *iface, WORD output_num, BOOL *allocate) @@ -813,7 +810,7 @@ static HRESULT WINAPI WMReaderAdvanced_GetMaxStreamSampleSize(IWMReaderAdvanced6
TRACE("reader %p, stream_number %u, size %p.\n", reader, stream_number, size);
- return wm_reader_get_max_stream_size(&reader->reader, stream_number, size); + return wm_reader_get_max_stream_size(reader->wm_reader, stream_number, size); }
static HRESULT WINAPI WMReaderAdvanced_NotifyLateDelivery(IWMReaderAdvanced6 *iface, QWORD lateness) @@ -935,9 +932,9 @@ static HRESULT WINAPI WMReaderAdvanced2_OpenStream(IWMReaderAdvanced6 *iface,
EnterCriticalSection(&reader->cs);
- if (SUCCEEDED(hr = wm_reader_open_stream(&reader->reader, stream)) + if (SUCCEEDED(hr = wm_reader_open_stream(reader->wm_reader, stream)) && FAILED(hr = async_reader_open(reader, callback, context))) - wm_reader_close(&reader->reader); + wm_reader_close(reader->wm_reader);
LeaveCriticalSection(&reader->cs); return hr; @@ -1108,19 +1105,19 @@ static struct async_reader *impl_from_IWMReaderAccelerator(IWMReaderAccelerator static HRESULT WINAPI reader_accl_QueryInterface(IWMReaderAccelerator *iface, REFIID iid, void **out) { struct async_reader *reader = impl_from_IWMReaderAccelerator(iface); - return IUnknown_QueryInterface(reader->reader.outer, iid, out); + return IWMReader_QueryInterface(&reader->IWMReader_iface, iid, out); }
static ULONG WINAPI reader_accl_AddRef(IWMReaderAccelerator *iface) { struct async_reader *reader = impl_from_IWMReaderAccelerator(iface); - return IUnknown_AddRef(reader->reader.outer); + return IWMReader_AddRef(&reader->IWMReader_iface); }
static ULONG WINAPI reader_accl_Release(IWMReaderAccelerator *iface) { struct async_reader *reader = impl_from_IWMReaderAccelerator(iface); - return IUnknown_Release(reader->reader.outer); + return IWMReader_Release(&reader->IWMReader_iface); }
static HRESULT WINAPI reader_accl_GetCodecInterface(IWMReaderAccelerator *iface, DWORD output, REFIID riid, void **codec) @@ -1157,19 +1154,19 @@ static struct async_reader *impl_from_IWMReaderNetworkConfig2(IWMReaderNetworkCo static HRESULT WINAPI networkconfig_QueryInterface(IWMReaderNetworkConfig2 *iface, REFIID iid, void **out) { struct async_reader *reader = impl_from_IWMReaderNetworkConfig2(iface); - return IUnknown_QueryInterface(reader->reader.outer, iid, out); + return IWMReader_QueryInterface(&reader->IWMReader_iface, iid, out); }
static ULONG WINAPI networkconfig_AddRef(IWMReaderNetworkConfig2 *iface) { struct async_reader *reader = impl_from_IWMReaderNetworkConfig2(iface); - return IUnknown_AddRef(reader->reader.outer); + return IWMReader_AddRef(&reader->IWMReader_iface); }
static ULONG WINAPI networkconfig_Release(IWMReaderNetworkConfig2 *iface) { struct async_reader *reader = impl_from_IWMReaderNetworkConfig2(iface); - return IUnknown_Release(reader->reader.outer); + return IWMReader_Release(&reader->IWMReader_iface); }
static HRESULT WINAPI networkconfig_GetBufferingTime(IWMReaderNetworkConfig2 *iface, QWORD *buffering_time) @@ -1585,19 +1582,19 @@ static struct async_reader *impl_from_IWMReaderStreamClock(IWMReaderStreamClock static HRESULT WINAPI readclock_QueryInterface(IWMReaderStreamClock *iface, REFIID iid, void **out) { struct async_reader *reader = impl_from_IWMReaderStreamClock(iface); - return IUnknown_QueryInterface(reader->reader.outer, iid, out); + return IWMReader_QueryInterface(&reader->IWMReader_iface, iid, out); }
static ULONG WINAPI readclock_AddRef(IWMReaderStreamClock *iface) { struct async_reader *reader = impl_from_IWMReaderStreamClock(iface); - return IUnknown_AddRef(reader->reader.outer); + return IWMReader_AddRef(&reader->IWMReader_iface); }
static ULONG WINAPI readclock_Release(IWMReaderStreamClock *iface) { struct async_reader *reader = impl_from_IWMReaderStreamClock(iface); - return IUnknown_Release(reader->reader.outer); + return IWMReader_Release(&reader->IWMReader_iface); }
static HRESULT WINAPI readclock_GetTime(IWMReaderStreamClock *iface, QWORD *now) @@ -1641,19 +1638,19 @@ static struct async_reader *impl_from_IWMReaderTypeNegotiation(IWMReaderTypeNego static HRESULT WINAPI negotiation_QueryInterface(IWMReaderTypeNegotiation *iface, REFIID iid, void **out) { struct async_reader *reader = impl_from_IWMReaderTypeNegotiation(iface); - return IUnknown_QueryInterface(reader->reader.outer, iid, out); + return IWMReader_QueryInterface(&reader->IWMReader_iface, iid, out); }
static ULONG WINAPI negotiation_AddRef(IWMReaderTypeNegotiation *iface) { struct async_reader *reader = impl_from_IWMReaderTypeNegotiation(iface); - return IUnknown_AddRef(reader->reader.outer); + return IWMReader_AddRef(&reader->IWMReader_iface); }
static ULONG WINAPI negotiation_Release(IWMReaderTypeNegotiation *iface) { struct async_reader *reader = impl_from_IWMReaderTypeNegotiation(iface); - return IUnknown_Release(reader->reader.outer); + return IWMReader_Release(&reader->IWMReader_iface); }
static HRESULT WINAPI negotiation_TryOutputProps(IWMReaderTypeNegotiation *iface, DWORD output, IWMOutputMediaProps *props) @@ -1681,19 +1678,19 @@ static struct async_reader *impl_from_IReferenceClock(IReferenceClock *iface) static HRESULT WINAPI refclock_QueryInterface(IReferenceClock *iface, REFIID iid, void **out) { struct async_reader *reader = impl_from_IReferenceClock(iface); - return IUnknown_QueryInterface(reader->reader.outer, iid, out); + return IWMReader_QueryInterface(&reader->IWMReader_iface, iid, out); }
static ULONG WINAPI refclock_AddRef(IReferenceClock *iface) { struct async_reader *reader = impl_from_IReferenceClock(iface); - return IUnknown_AddRef(reader->reader.outer); + return IWMReader_AddRef(&reader->IWMReader_iface); }
static ULONG WINAPI refclock_Release(IReferenceClock *iface) { struct async_reader *reader = impl_from_IReferenceClock(iface); - return IUnknown_Release(reader->reader.outer); + return IWMReader_Release(&reader->IWMReader_iface); }
static HRESULT WINAPI refclock_GetTime(IReferenceClock *iface, REFERENCE_TIME *time) @@ -1748,6 +1745,7 @@ static const IReferenceClockVtbl ReferenceClockVtbl = HRESULT WINAPI winegstreamer_create_wm_async_reader(IWMReader **reader) { struct async_reader *object; + HRESULT hr;
TRACE("reader %p.\n", reader);
@@ -1761,9 +1759,13 @@ HRESULT WINAPI winegstreamer_create_wm_async_reader(IWMReader **reader) object->IWMReaderNetworkConfig2_iface.lpVtbl = &WMReaderNetworkConfig2Vtbl; object->IWMReaderStreamClock_iface.lpVtbl = &WMReaderStreamClockVtbl; object->IWMReaderTypeNegotiation_iface.lpVtbl = &WMReaderTypeNegotiationVtbl; - wm_reader_init((IUnknown *)&object->IWMReader_iface, &object->reader); object->refcount = 1;
+ if (FAILED(hr = winegstreamer_create_wm_sync_reader((IUnknown *)&object->IWMReader_iface, + (void **)&object->reader_inner))) + goto failed; + object->wm_reader = wm_reader_from_sync_reader_inner(object->reader_inner); + InitializeCriticalSection(&object->cs); object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": async_reader.cs"); InitializeCriticalSection(&object->callback_cs); @@ -1775,4 +1777,10 @@ HRESULT WINAPI winegstreamer_create_wm_async_reader(IWMReader **reader) TRACE("Created async reader %p.\n", object); *reader = (IWMReader *)&object->IWMReader_iface; return S_OK; + +failed: + if (object->reader_inner) + IUnknown_Release(object->reader_inner); + free(object); + return hr; } diff --git a/dlls/winegstreamer/wm_syncreader.c b/dlls/winegstreamer/wm_syncreader.c index 814d38cc089..7b484d5f3c2 100644 --- a/dlls/winegstreamer/wm_syncreader.c +++ b/dlls/winegstreamer/wm_syncreader.c @@ -22,19 +22,20 @@ WINE_DEFAULT_DEBUG_CHANNEL(wmvcore);
struct sync_reader { + IUnknown IUnknown_inner; IWMSyncReader2 IWMSyncReader2_iface; struct wm_reader reader; LONG refcount; };
-static struct sync_reader *impl_from_IWMSyncReader2(IWMSyncReader2 *iface) +static struct sync_reader *impl_from_IUnknown(IUnknown *iface) { - return CONTAINING_RECORD(iface, struct sync_reader, IWMSyncReader2_iface); + return CONTAINING_RECORD(iface, struct sync_reader, IUnknown_inner); }
-static HRESULT WINAPI WMSyncReader_QueryInterface(IWMSyncReader2 *iface, REFIID iid, void **out) +static HRESULT WINAPI unknown_inner_QueryInterface(IUnknown *iface, REFIID iid, void **out) { - struct sync_reader *reader = impl_from_IWMSyncReader2(iface); + struct sync_reader *reader = impl_from_IUnknown(iface);
TRACE("reader %p, iid %s, out %p.\n", reader, debugstr_guid(iid), out);
@@ -69,17 +70,17 @@ static HRESULT WINAPI WMSyncReader_QueryInterface(IWMSyncReader2 *iface, REFIID return S_OK; }
-static ULONG WINAPI WMSyncReader_AddRef(IWMSyncReader2 *iface) +static ULONG WINAPI unknown_inner_AddRef(IUnknown *iface) { - struct sync_reader *reader = impl_from_IWMSyncReader2(iface); + struct sync_reader *reader = impl_from_IUnknown(iface); ULONG refcount = InterlockedIncrement(&reader->refcount); TRACE("%p increasing refcount to %lu.\n", reader, refcount); return refcount; }
-static ULONG WINAPI WMSyncReader_Release(IWMSyncReader2 *iface) +static ULONG WINAPI unknown_inner_Release(IUnknown *iface) { - struct sync_reader *reader = impl_from_IWMSyncReader2(iface); + struct sync_reader *reader = impl_from_IUnknown(iface); ULONG refcount = InterlockedDecrement(&reader->refcount);
TRACE("%p decreasing refcount to %lu.\n", reader, refcount); @@ -94,6 +95,36 @@ static ULONG WINAPI WMSyncReader_Release(IWMSyncReader2 *iface) return refcount; }
+static const IUnknownVtbl unknown_inner_vtbl = +{ + unknown_inner_QueryInterface, + unknown_inner_AddRef, + unknown_inner_Release, +}; + +static struct sync_reader *impl_from_IWMSyncReader2(IWMSyncReader2 *iface) +{ + return CONTAINING_RECORD(iface, struct sync_reader, IWMSyncReader2_iface); +} + +static HRESULT WINAPI WMSyncReader_QueryInterface(IWMSyncReader2 *iface, REFIID iid, void **out) +{ + struct sync_reader *reader = impl_from_IWMSyncReader2(iface); + return IUnknown_QueryInterface(reader->reader.outer, iid, out); +} + +static ULONG WINAPI WMSyncReader_AddRef(IWMSyncReader2 *iface) +{ + struct sync_reader *reader = impl_from_IWMSyncReader2(iface); + return IUnknown_AddRef(reader->reader.outer); +} + +static ULONG WINAPI WMSyncReader_Release(IWMSyncReader2 *iface) +{ + struct sync_reader *reader = impl_from_IWMSyncReader2(iface); + return IUnknown_Release(reader->reader.outer); +} + static HRESULT WINAPI WMSyncReader_Close(IWMSyncReader2 *iface) { struct sync_reader *reader = impl_from_IWMSyncReader2(iface); @@ -404,20 +435,27 @@ static const IWMSyncReader2Vtbl WMSyncReader2Vtbl = { WMSyncReader2_GetAllocateForStream };
-HRESULT WINAPI winegstreamer_create_wm_sync_reader(IWMSyncReader **reader) +struct wm_reader *wm_reader_from_sync_reader_inner(IUnknown *iface) +{ + struct sync_reader *reader = impl_from_IUnknown(iface); + return &reader->reader; +} + +HRESULT WINAPI winegstreamer_create_wm_sync_reader(IUnknown *outer, void **out) { struct sync_reader *object;
- TRACE("reader %p.\n", reader); + TRACE("out %p.\n", out);
if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY;
+ object->IUnknown_inner.lpVtbl = &unknown_inner_vtbl; object->IWMSyncReader2_iface.lpVtbl = &WMSyncReader2Vtbl; - wm_reader_init((IUnknown *)&object->IWMSyncReader2_iface, &object->reader); + wm_reader_init(outer ? outer : &object->IUnknown_inner, &object->reader); object->refcount = 1;
TRACE("Created sync reader %p.\n", object); - *reader = (IWMSyncReader *)&object->IWMSyncReader2_iface; + *out = outer ? (void *)&object->IUnknown_inner : (void *)&object->IWMSyncReader2_iface; return S_OK; } diff --git a/dlls/wmvcore/wmvcore_main.c b/dlls/wmvcore/wmvcore_main.c index 4be55cbb707..bae37cd1cff 100644 --- a/dlls/wmvcore/wmvcore_main.c +++ b/dlls/wmvcore/wmvcore_main.c @@ -26,7 +26,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(wmvcore);
HRESULT WINAPI winegstreamer_create_wm_async_reader(IWMReader **reader); -HRESULT WINAPI winegstreamer_create_wm_sync_reader(IWMSyncReader **reader); +HRESULT WINAPI winegstreamer_create_wm_sync_reader(IUnknown *outer, void **out);
HRESULT WINAPI WMCreateReader(IUnknown *reserved, DWORD rights, IWMReader **reader) { @@ -46,14 +46,14 @@ HRESULT WINAPI WMCreateSyncReader(IUnknown *reserved, DWORD rights, IWMSyncReade { TRACE("reserved %p, rights %#lx, reader %p.\n", reserved, rights, reader);
- return winegstreamer_create_wm_sync_reader(reader); + return winegstreamer_create_wm_sync_reader(NULL, (void **)reader); }
HRESULT WINAPI WMCreateSyncReaderPriv(IWMSyncReader **reader) { TRACE("reader %p.\n", reader);
- return winegstreamer_create_wm_sync_reader(reader); + return winegstreamer_create_wm_sync_reader(NULL, (void **)reader); }
HRESULT WINAPI WMCheckURLExtension(const WCHAR *url)
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/Makefile.in | 1 - dlls/winegstreamer/gst_private.h | 5 +- dlls/winegstreamer/wm_reader.c | 450 +++++++++++++++++++++++++++- dlls/winegstreamer/wm_syncreader.c | 461 ----------------------------- 4 files changed, 440 insertions(+), 477 deletions(-) delete mode 100644 dlls/winegstreamer/wm_syncreader.c
diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in index 791b9bfd547..2245500f0c3 100644 --- a/dlls/winegstreamer/Makefile.in +++ b/dlls/winegstreamer/Makefile.in @@ -23,7 +23,6 @@ C_SRCS = \ wg_transform.c \ wm_asyncreader.c \ wm_reader.c \ - wm_syncreader.c \ wma_decoder.c
IDL_SRCS = \ diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index f916fde8318..c4d1be54364 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -162,6 +162,8 @@ struct wm_stream
struct wm_reader { + IUnknown IUnknown_inner; + IWMSyncReader2 IWMSyncReader2_iface; IWMHeaderInfo3 IWMHeaderInfo3_iface; IWMLanguageList IWMLanguageList_iface; IWMPacketSize2 IWMPacketSize2_iface; @@ -169,6 +171,7 @@ struct wm_reader IWMReaderPlaylistBurn IWMReaderPlaylistBurn_iface; IWMReaderTimecode IWMReaderTimecode_iface; IUnknown *outer; + LONG refcount;
CRITICAL_SECTION cs; QWORD start_time; @@ -186,7 +189,6 @@ struct wm_reader HRESULT WINAPI winegstreamer_create_wm_sync_reader(IUnknown *outer, void **out); struct wm_reader *wm_reader_from_sync_reader_inner(IUnknown *inner);
-void wm_reader_cleanup(struct wm_reader *reader); HRESULT wm_reader_close(struct wm_reader *reader); HRESULT wm_reader_get_max_stream_size(struct wm_reader *reader, WORD stream_number, DWORD *size); HRESULT wm_reader_get_output_format(struct wm_reader *reader, DWORD output, @@ -200,7 +202,6 @@ HRESULT wm_reader_get_stream_sample(struct wm_reader *reader, IWMReaderCallbackA INSSBuffer **ret_sample, QWORD *pts, QWORD *duration, DWORD *flags, WORD *ret_stream_number); HRESULT wm_reader_get_stream_selection(struct wm_reader *reader, WORD stream_number, WMT_STREAM_SELECTION *selection); -void wm_reader_init(IUnknown *outer, struct wm_reader *reader); HRESULT wm_reader_open_file(struct wm_reader *reader, const WCHAR *filename); HRESULT wm_reader_open_stream(struct wm_reader *reader, IStream *stream); void wm_reader_seek(struct wm_reader *reader, QWORD start, LONGLONG duration); diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c index 5d7a209bfc9..85332926d49 100644 --- a/dlls/winegstreamer/wm_reader.c +++ b/dlls/winegstreamer/wm_reader.c @@ -2139,22 +2139,446 @@ HRESULT wm_reader_get_max_stream_size(struct wm_reader *reader, WORD stream_numb return S_OK; }
-void wm_reader_init(IUnknown *outer, struct wm_reader *reader) +static struct wm_reader *impl_from_IUnknown(IUnknown *iface) +{ + return CONTAINING_RECORD(iface, struct wm_reader, IUnknown_inner); +} + +static HRESULT WINAPI unknown_inner_QueryInterface(IUnknown *iface, REFIID iid, void **out) +{ + struct wm_reader *reader = impl_from_IUnknown(iface); + + TRACE("reader %p, iid %s, out %p.\n", reader, debugstr_guid(iid), out); + + if (IsEqualIID(iid, &IID_IUnknown) + || IsEqualIID(iid, &IID_IWMSyncReader) + || IsEqualIID(iid, &IID_IWMSyncReader2)) + *out = &reader->IWMSyncReader2_iface; + else if (IsEqualIID(iid, &IID_IWMHeaderInfo) + || IsEqualIID(iid, &IID_IWMHeaderInfo2) + || IsEqualIID(iid, &IID_IWMHeaderInfo3)) + *out = &reader->IWMHeaderInfo3_iface; + else if (IsEqualIID(iid, &IID_IWMLanguageList)) + *out = &reader->IWMLanguageList_iface; + else if (IsEqualIID(iid, &IID_IWMPacketSize) + || IsEqualIID(iid, &IID_IWMPacketSize2)) + *out = &reader->IWMPacketSize2_iface; + else if (IsEqualIID(iid, &IID_IWMProfile) + || IsEqualIID(iid, &IID_IWMProfile2) + || IsEqualIID(iid, &IID_IWMProfile3)) + *out = &reader->IWMProfile3_iface; + else if (IsEqualIID(iid, &IID_IWMReaderPlaylistBurn)) + *out = &reader->IWMReaderPlaylistBurn_iface; + else if (IsEqualIID(iid, &IID_IWMReaderTimecode)) + *out = &reader->IWMReaderTimecode_iface; + else + { + WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown *)*out); + return S_OK; +} + +static ULONG WINAPI unknown_inner_AddRef(IUnknown *iface) +{ + struct wm_reader *reader = impl_from_IUnknown(iface); + ULONG refcount = InterlockedIncrement(&reader->refcount); + TRACE("%p increasing refcount to %lu.\n", reader, refcount); + return refcount; +} + +static ULONG WINAPI unknown_inner_Release(IUnknown *iface) { - reader->IWMHeaderInfo3_iface.lpVtbl = &header_info_vtbl; - reader->IWMLanguageList_iface.lpVtbl = &language_list_vtbl; - reader->IWMPacketSize2_iface.lpVtbl = &packet_size_vtbl; - reader->IWMProfile3_iface.lpVtbl = &profile_vtbl; - reader->IWMReaderPlaylistBurn_iface.lpVtbl = &playlist_vtbl; - reader->IWMReaderTimecode_iface.lpVtbl = &timecode_vtbl; - reader->outer = outer; + struct wm_reader *reader = impl_from_IUnknown(iface); + ULONG refcount = InterlockedDecrement(&reader->refcount); + + TRACE("%p decreasing refcount to %lu.\n", reader, refcount); + + if (!refcount) + { + wm_reader_close(reader); + + reader->cs.DebugInfo->Spare[0] = 0; + DeleteCriticalSection(&reader->cs); + + free(reader); + } + + return refcount; +} + +static const IUnknownVtbl unknown_inner_vtbl = +{ + unknown_inner_QueryInterface, + unknown_inner_AddRef, + unknown_inner_Release, +};
- InitializeCriticalSection(&reader->cs); - reader->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": wm_reader.cs"); +static struct wm_reader *impl_from_IWMSyncReader2(IWMSyncReader2 *iface) +{ + return CONTAINING_RECORD(iface, struct wm_reader, IWMSyncReader2_iface); +} + +static HRESULT WINAPI reader_QueryInterface(IWMSyncReader2 *iface, REFIID iid, void **out) +{ + struct wm_reader *reader = impl_from_IWMSyncReader2(iface); + return IUnknown_QueryInterface(reader->outer, iid, out); +} + +static ULONG WINAPI reader_AddRef(IWMSyncReader2 *iface) +{ + struct wm_reader *reader = impl_from_IWMSyncReader2(iface); + return IUnknown_AddRef(reader->outer); +} + +static ULONG WINAPI reader_Release(IWMSyncReader2 *iface) +{ + struct wm_reader *reader = impl_from_IWMSyncReader2(iface); + return IUnknown_Release(reader->outer); +} + +static HRESULT WINAPI reader_Close(IWMSyncReader2 *iface) +{ + struct wm_reader *reader = impl_from_IWMSyncReader2(iface); + + TRACE("reader %p.\n", reader); + + return wm_reader_close(reader); +} + +static HRESULT WINAPI reader_GetMaxOutputSampleSize(IWMSyncReader2 *iface, DWORD output, DWORD *max) +{ + struct wm_reader *This = impl_from_IWMSyncReader2(iface); + FIXME("(%p)->(%lu %p): stub!\n", This, output, max); + return E_NOTIMPL; +} + +static HRESULT WINAPI reader_GetMaxStreamSampleSize(IWMSyncReader2 *iface, WORD stream, DWORD *max) +{ + struct wm_reader *This = impl_from_IWMSyncReader2(iface); + FIXME("(%p)->(%d %p): stub!\n", This, stream, max); + return E_NOTIMPL; +} + +static HRESULT WINAPI reader_GetNextSample(IWMSyncReader2 *iface, + WORD stream_number, INSSBuffer **sample, QWORD *pts, QWORD *duration, + DWORD *flags, DWORD *output_number, WORD *ret_stream_number) +{ + struct wm_reader *reader = impl_from_IWMSyncReader2(iface); + HRESULT hr = NS_E_NO_MORE_SAMPLES; + + TRACE("reader %p, stream_number %u, sample %p, pts %p, duration %p," + " flags %p, output_number %p, ret_stream_number %p.\n", + reader, stream_number, sample, pts, duration, flags, output_number, ret_stream_number); + + if (!stream_number && !output_number && !ret_stream_number) + return E_INVALIDARG; + + EnterCriticalSection(&reader->cs); + + hr = wm_reader_get_stream_sample(reader, NULL, stream_number, sample, pts, duration, flags, &stream_number); + if (output_number && hr == S_OK) + *output_number = stream_number - 1; + if (ret_stream_number && (hr == S_OK || stream_number)) + *ret_stream_number = stream_number; + + LeaveCriticalSection(&reader->cs); + return hr; +} + +static HRESULT WINAPI reader_GetOutputCount(IWMSyncReader2 *iface, DWORD *count) +{ + struct wm_reader *reader = impl_from_IWMSyncReader2(iface); + + TRACE("reader %p, count %p.\n", reader, count); + + EnterCriticalSection(&reader->cs); + *count = reader->stream_count; + LeaveCriticalSection(&reader->cs); + return S_OK; +} + +static HRESULT WINAPI reader_GetOutputFormat(IWMSyncReader2 *iface, + DWORD output, DWORD index, IWMOutputMediaProps **props) +{ + struct wm_reader *reader = impl_from_IWMSyncReader2(iface); + + TRACE("reader %p, output %lu, index %lu, props %p.\n", reader, output, index, props); + + return wm_reader_get_output_format(reader, output, index, props); +} + +static HRESULT WINAPI reader_GetOutputFormatCount(IWMSyncReader2 *iface, DWORD output, DWORD *count) +{ + struct wm_reader *reader = impl_from_IWMSyncReader2(iface); + + TRACE("reader %p, output %lu, count %p.\n", reader, output, count); + + return wm_reader_get_output_format_count(reader, output, count); +} + +static HRESULT WINAPI reader_GetOutputNumberForStream(IWMSyncReader2 *iface, + WORD stream_number, DWORD *output) +{ + struct wm_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 reader_GetOutputProps(IWMSyncReader2 *iface, + DWORD output, IWMOutputMediaProps **props) +{ + struct wm_reader *reader = impl_from_IWMSyncReader2(iface); + + TRACE("reader %p, output %lu, props %p.\n", reader, output, props); + + return wm_reader_get_output_props(reader, output, props); +} + +static HRESULT WINAPI reader_GetOutputSetting(IWMSyncReader2 *iface, DWORD output_num, const WCHAR *name, + WMT_ATTR_DATATYPE *type, BYTE *value, WORD *length) +{ + struct wm_reader *This = impl_from_IWMSyncReader2(iface); + FIXME("(%p)->(%lu %s %p %p %p): stub!\n", This, output_num, debugstr_w(name), type, value, length); + return E_NOTIMPL; +} + +static HRESULT WINAPI reader_GetReadStreamSamples(IWMSyncReader2 *iface, WORD stream_num, BOOL *compressed) +{ + struct wm_reader *This = impl_from_IWMSyncReader2(iface); + FIXME("(%p)->(%d %p): stub!\n", This, stream_num, compressed); + return E_NOTIMPL; }
-void wm_reader_cleanup(struct wm_reader *reader) +static HRESULT WINAPI reader_GetStreamNumberForOutput(IWMSyncReader2 *iface, + DWORD output, WORD *stream_number) { - reader->cs.DebugInfo->Spare[0] = 0; - DeleteCriticalSection(&reader->cs); + struct wm_reader *reader = impl_from_IWMSyncReader2(iface); + + TRACE("reader %p, output %lu, stream_number %p.\n", reader, output, stream_number); + + *stream_number = output + 1; + return S_OK; +} + +static HRESULT WINAPI reader_GetStreamSelected(IWMSyncReader2 *iface, + WORD stream_number, WMT_STREAM_SELECTION *selection) +{ + struct wm_reader *reader = impl_from_IWMSyncReader2(iface); + + TRACE("reader %p, stream_number %u, selection %p.\n", reader, stream_number, selection); + + return wm_reader_get_stream_selection(reader, stream_number, selection); +} + +static HRESULT WINAPI reader_Open(IWMSyncReader2 *iface, const WCHAR *filename) +{ + struct wm_reader *reader = impl_from_IWMSyncReader2(iface); + + TRACE("reader %p, filename %s.\n", reader, debugstr_w(filename)); + + return wm_reader_open_file(reader, filename); +} + +static HRESULT WINAPI reader_OpenStream(IWMSyncReader2 *iface, IStream *stream) +{ + struct wm_reader *reader = impl_from_IWMSyncReader2(iface); + + TRACE("reader %p, stream %p.\n", reader, stream); + + return wm_reader_open_stream(reader, stream); +} + +static HRESULT WINAPI reader_SetOutputProps(IWMSyncReader2 *iface, DWORD output, IWMOutputMediaProps *props) +{ + struct wm_reader *reader = impl_from_IWMSyncReader2(iface); + + TRACE("reader %p, output %lu, props %p.\n", reader, output, props); + + return wm_reader_set_output_props(reader, output, props); +} + +static HRESULT WINAPI reader_SetOutputSetting(IWMSyncReader2 *iface, DWORD output, + const WCHAR *name, WMT_ATTR_DATATYPE type, const BYTE *value, WORD size) +{ + struct wm_reader *reader = impl_from_IWMSyncReader2(iface); + + TRACE("reader %p, output %lu, name %s, type %#x, value %p, size %u.\n", + reader, output, debugstr_w(name), type, value, size); + + if (!wcscmp(name, L"VideoSampleDurations")) + { + FIXME("Ignoring VideoSampleDurations setting.\n"); + return S_OK; + } + if (!wcscmp(name, L"EnableDiscreteOutput")) + { + FIXME("Ignoring EnableDiscreteOutput setting.\n"); + return S_OK; + } + if (!wcscmp(name, L"SpeakerConfig")) + { + FIXME("Ignoring SpeakerConfig setting.\n"); + return S_OK; + } + else + { + FIXME("Unknown setting %s; returning E_NOTIMPL.\n", debugstr_w(name)); + return E_NOTIMPL; + } +} + +static HRESULT WINAPI reader_SetRange(IWMSyncReader2 *iface, QWORD start, LONGLONG duration) +{ + struct wm_reader *reader = impl_from_IWMSyncReader2(iface); + + TRACE("reader %p, start %I64u, duration %I64d.\n", reader, start, duration); + + wm_reader_seek(reader, start, duration); + return S_OK; +} + +static HRESULT WINAPI reader_SetRangeByFrame(IWMSyncReader2 *iface, WORD stream_num, QWORD frame_num, + LONGLONG frames) +{ + struct wm_reader *This = impl_from_IWMSyncReader2(iface); + FIXME("(%p)->(%d %s %s): stub!\n", This, stream_num, wine_dbgstr_longlong(frame_num), wine_dbgstr_longlong(frames)); + return E_NOTIMPL; +} + +static HRESULT WINAPI reader_SetReadStreamSamples(IWMSyncReader2 *iface, WORD stream_number, BOOL compressed) +{ + struct wm_reader *reader = impl_from_IWMSyncReader2(iface); + + TRACE("reader %p, stream_index %u, compressed %d.\n", reader, stream_number, compressed); + + return wm_reader_set_read_compressed(reader, stream_number, compressed); +} + +static HRESULT WINAPI reader_SetStreamsSelected(IWMSyncReader2 *iface, + WORD count, WORD *stream_numbers, WMT_STREAM_SELECTION *selections) +{ + struct wm_reader *reader = impl_from_IWMSyncReader2(iface); + + TRACE("reader %p, count %u, stream_numbers %p, selections %p.\n", + reader, count, stream_numbers, selections); + + return wm_reader_set_streams_selected(reader, count, stream_numbers, selections); +} + +static HRESULT WINAPI reader_SetRangeByTimecode(IWMSyncReader2 *iface, WORD stream_num, + WMT_TIMECODE_EXTENSION_DATA *start, WMT_TIMECODE_EXTENSION_DATA *end) +{ + struct wm_reader *This = impl_from_IWMSyncReader2(iface); + FIXME("(%p)->(%u %p %p): stub!\n", This, stream_num, start, end); + return E_NOTIMPL; +} + +static HRESULT WINAPI reader_SetRangeByFrameEx(IWMSyncReader2 *iface, WORD stream_num, QWORD frame_num, + LONGLONG frames_to_read, QWORD *starttime) +{ + struct wm_reader *This = impl_from_IWMSyncReader2(iface); + FIXME("(%p)->(%u %s %s %p): stub!\n", This, stream_num, wine_dbgstr_longlong(frame_num), + wine_dbgstr_longlong(frames_to_read), starttime); + return E_NOTIMPL; +} + +static HRESULT WINAPI reader_SetAllocateForOutput(IWMSyncReader2 *iface, DWORD output_num, IWMReaderAllocatorEx *allocator) +{ + struct wm_reader *This = impl_from_IWMSyncReader2(iface); + FIXME("(%p)->(%lu %p): stub!\n", This, output_num, allocator); + return E_NOTIMPL; +} + +static HRESULT WINAPI reader_GetAllocateForOutput(IWMSyncReader2 *iface, DWORD output_num, IWMReaderAllocatorEx **allocator) +{ + struct wm_reader *This = impl_from_IWMSyncReader2(iface); + FIXME("(%p)->(%lu %p): stub!\n", This, output_num, allocator); + return E_NOTIMPL; +} + +static HRESULT WINAPI reader_SetAllocateForStream(IWMSyncReader2 *iface, DWORD stream_num, IWMReaderAllocatorEx *allocator) +{ + struct wm_reader *This = impl_from_IWMSyncReader2(iface); + FIXME("(%p)->(%lu %p): stub!\n", This, stream_num, allocator); + return E_NOTIMPL; +} + +static HRESULT WINAPI reader_GetAllocateForStream(IWMSyncReader2 *iface, DWORD stream_num, IWMReaderAllocatorEx **allocator) +{ + struct wm_reader *This = impl_from_IWMSyncReader2(iface); + FIXME("(%p)->(%lu %p): stub!\n", This, stream_num, allocator); + return E_NOTIMPL; +} + +static const IWMSyncReader2Vtbl reader_vtbl = +{ + reader_QueryInterface, + reader_AddRef, + reader_Release, + reader_Open, + reader_Close, + reader_SetRange, + reader_SetRangeByFrame, + reader_GetNextSample, + reader_SetStreamsSelected, + reader_GetStreamSelected, + reader_SetReadStreamSamples, + reader_GetReadStreamSamples, + reader_GetOutputSetting, + reader_SetOutputSetting, + reader_GetOutputCount, + reader_GetOutputProps, + reader_SetOutputProps, + reader_GetOutputFormatCount, + reader_GetOutputFormat, + reader_GetOutputNumberForStream, + reader_GetStreamNumberForOutput, + reader_GetMaxOutputSampleSize, + reader_GetMaxStreamSampleSize, + reader_OpenStream, + reader_SetRangeByTimecode, + reader_SetRangeByFrameEx, + reader_SetAllocateForOutput, + reader_GetAllocateForOutput, + reader_SetAllocateForStream, + reader_GetAllocateForStream +}; + +struct wm_reader *wm_reader_from_sync_reader_inner(IUnknown *iface) +{ + return impl_from_IUnknown(iface); +} + +HRESULT WINAPI winegstreamer_create_wm_sync_reader(IUnknown *outer, void **out) +{ + struct wm_reader *object; + + TRACE("out %p.\n", out); + + if (!(object = calloc(1, sizeof(*object)))) + return E_OUTOFMEMORY; + + object->IUnknown_inner.lpVtbl = &unknown_inner_vtbl; + object->IWMSyncReader2_iface.lpVtbl = &reader_vtbl; + object->IWMHeaderInfo3_iface.lpVtbl = &header_info_vtbl; + object->IWMLanguageList_iface.lpVtbl = &language_list_vtbl; + object->IWMPacketSize2_iface.lpVtbl = &packet_size_vtbl; + object->IWMProfile3_iface.lpVtbl = &profile_vtbl; + object->IWMReaderPlaylistBurn_iface.lpVtbl = &playlist_vtbl; + object->IWMReaderTimecode_iface.lpVtbl = &timecode_vtbl; + object->outer = outer ? outer : &object->IUnknown_inner; + object->refcount = 1; + + InitializeCriticalSection(&object->cs); + object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": reader.cs"); + + TRACE("Created reader %p.\n", object); + *out = outer ? (void *)&object->IUnknown_inner : (void *)&object->IWMSyncReader2_iface; + return S_OK; } diff --git a/dlls/winegstreamer/wm_syncreader.c b/dlls/winegstreamer/wm_syncreader.c deleted file mode 100644 index 7b484d5f3c2..00000000000 --- a/dlls/winegstreamer/wm_syncreader.c +++ /dev/null @@ -1,461 +0,0 @@ -/* - * Copyright 2012 Austin English - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "gst_private.h" - -WINE_DEFAULT_DEBUG_CHANNEL(wmvcore); - -struct sync_reader -{ - IUnknown IUnknown_inner; - IWMSyncReader2 IWMSyncReader2_iface; - struct wm_reader reader; - LONG refcount; -}; - -static struct sync_reader *impl_from_IUnknown(IUnknown *iface) -{ - return CONTAINING_RECORD(iface, struct sync_reader, IUnknown_inner); -} - -static HRESULT WINAPI unknown_inner_QueryInterface(IUnknown *iface, REFIID iid, void **out) -{ - struct sync_reader *reader = impl_from_IUnknown(iface); - - TRACE("reader %p, iid %s, out %p.\n", reader, debugstr_guid(iid), out); - - if (IsEqualIID(iid, &IID_IUnknown) - || IsEqualIID(iid, &IID_IWMSyncReader) - || IsEqualIID(iid, &IID_IWMSyncReader2)) - *out = &reader->IWMSyncReader2_iface; - else if (IsEqualIID(iid, &IID_IWMHeaderInfo) - || IsEqualIID(iid, &IID_IWMHeaderInfo2) - || IsEqualIID(iid, &IID_IWMHeaderInfo3)) - *out = &reader->reader.IWMHeaderInfo3_iface; - else if (IsEqualIID(iid, &IID_IWMLanguageList)) - *out = &reader->reader.IWMLanguageList_iface; - else if (IsEqualIID(iid, &IID_IWMPacketSize) - || IsEqualIID(iid, &IID_IWMPacketSize2)) - *out = &reader->reader.IWMPacketSize2_iface; - else if (IsEqualIID(iid, &IID_IWMProfile) - || IsEqualIID(iid, &IID_IWMProfile2) - || IsEqualIID(iid, &IID_IWMProfile3)) - *out = &reader->reader.IWMProfile3_iface; - else if (IsEqualIID(iid, &IID_IWMReaderPlaylistBurn)) - *out = &reader->reader.IWMReaderPlaylistBurn_iface; - else if (IsEqualIID(iid, &IID_IWMReaderTimecode)) - *out = &reader->reader.IWMReaderTimecode_iface; - else - { - WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(iid)); - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown *)*out); - return S_OK; -} - -static ULONG WINAPI unknown_inner_AddRef(IUnknown *iface) -{ - struct sync_reader *reader = impl_from_IUnknown(iface); - ULONG refcount = InterlockedIncrement(&reader->refcount); - TRACE("%p increasing refcount to %lu.\n", reader, refcount); - return refcount; -} - -static ULONG WINAPI unknown_inner_Release(IUnknown *iface) -{ - struct sync_reader *reader = impl_from_IUnknown(iface); - ULONG refcount = InterlockedDecrement(&reader->refcount); - - TRACE("%p decreasing refcount to %lu.\n", reader, refcount); - - if (!refcount) - { - wm_reader_close(&reader->reader); - wm_reader_cleanup(&reader->reader); - free(reader); - } - - return refcount; -} - -static const IUnknownVtbl unknown_inner_vtbl = -{ - unknown_inner_QueryInterface, - unknown_inner_AddRef, - unknown_inner_Release, -}; - -static struct sync_reader *impl_from_IWMSyncReader2(IWMSyncReader2 *iface) -{ - return CONTAINING_RECORD(iface, struct sync_reader, IWMSyncReader2_iface); -} - -static HRESULT WINAPI WMSyncReader_QueryInterface(IWMSyncReader2 *iface, REFIID iid, void **out) -{ - struct sync_reader *reader = impl_from_IWMSyncReader2(iface); - return IUnknown_QueryInterface(reader->reader.outer, iid, out); -} - -static ULONG WINAPI WMSyncReader_AddRef(IWMSyncReader2 *iface) -{ - struct sync_reader *reader = impl_from_IWMSyncReader2(iface); - return IUnknown_AddRef(reader->reader.outer); -} - -static ULONG WINAPI WMSyncReader_Release(IWMSyncReader2 *iface) -{ - struct sync_reader *reader = impl_from_IWMSyncReader2(iface); - return IUnknown_Release(reader->reader.outer); -} - -static HRESULT WINAPI WMSyncReader_Close(IWMSyncReader2 *iface) -{ - struct sync_reader *reader = impl_from_IWMSyncReader2(iface); - - TRACE("reader %p.\n", reader); - - return wm_reader_close(&reader->reader); -} - -static HRESULT WINAPI WMSyncReader_GetMaxOutputSampleSize(IWMSyncReader2 *iface, DWORD output, DWORD *max) -{ - struct sync_reader *This = impl_from_IWMSyncReader2(iface); - FIXME("(%p)->(%lu %p): stub!\n", This, output, max); - return E_NOTIMPL; -} - -static HRESULT WINAPI WMSyncReader_GetMaxStreamSampleSize(IWMSyncReader2 *iface, WORD stream, DWORD *max) -{ - struct sync_reader *This = impl_from_IWMSyncReader2(iface); - FIXME("(%p)->(%d %p): stub!\n", This, stream, max); - return E_NOTIMPL; -} - -static HRESULT WINAPI WMSyncReader_GetNextSample(IWMSyncReader2 *iface, - WORD stream_number, INSSBuffer **sample, QWORD *pts, QWORD *duration, - DWORD *flags, DWORD *output_number, WORD *ret_stream_number) -{ - struct sync_reader *reader = impl_from_IWMSyncReader2(iface); - HRESULT hr = NS_E_NO_MORE_SAMPLES; - - TRACE("reader %p, stream_number %u, sample %p, pts %p, duration %p," - " flags %p, output_number %p, ret_stream_number %p.\n", - reader, stream_number, sample, pts, duration, flags, output_number, ret_stream_number); - - if (!stream_number && !output_number && !ret_stream_number) - return E_INVALIDARG; - - EnterCriticalSection(&reader->reader.cs); - - hr = wm_reader_get_stream_sample(&reader->reader, NULL, stream_number, sample, pts, duration, flags, &stream_number); - if (output_number && hr == S_OK) - *output_number = stream_number - 1; - if (ret_stream_number && (hr == S_OK || stream_number)) - *ret_stream_number = stream_number; - - LeaveCriticalSection(&reader->reader.cs); - return hr; -} - -static HRESULT WINAPI WMSyncReader_GetOutputCount(IWMSyncReader2 *iface, DWORD *count) -{ - 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, DWORD index, IWMOutputMediaProps **props) -{ - struct sync_reader *reader = impl_from_IWMSyncReader2(iface); - - TRACE("reader %p, output %lu, index %lu, props %p.\n", reader, output, index, props); - - return wm_reader_get_output_format(&reader->reader, output, index, props); -} - -static HRESULT WINAPI WMSyncReader_GetOutputFormatCount(IWMSyncReader2 *iface, DWORD output, DWORD *count) -{ - struct sync_reader *reader = impl_from_IWMSyncReader2(iface); - - TRACE("reader %p, output %lu, count %p.\n", reader, output, count); - - return wm_reader_get_output_format_count(&reader->reader, output, count); -} - -static HRESULT WINAPI WMSyncReader_GetOutputNumberForStream(IWMSyncReader2 *iface, - WORD stream_number, DWORD *output) -{ - 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, IWMOutputMediaProps **props) -{ - struct sync_reader *reader = impl_from_IWMSyncReader2(iface); - - TRACE("reader %p, output %lu, props %p.\n", reader, output, props); - - return wm_reader_get_output_props(&reader->reader, output, props); -} - -static HRESULT WINAPI WMSyncReader_GetOutputSetting(IWMSyncReader2 *iface, DWORD output_num, const WCHAR *name, - WMT_ATTR_DATATYPE *type, BYTE *value, WORD *length) -{ - struct sync_reader *This = impl_from_IWMSyncReader2(iface); - FIXME("(%p)->(%lu %s %p %p %p): stub!\n", This, output_num, debugstr_w(name), type, value, length); - return E_NOTIMPL; -} - -static HRESULT WINAPI WMSyncReader_GetReadStreamSamples(IWMSyncReader2 *iface, WORD stream_num, BOOL *compressed) -{ - struct sync_reader *This = impl_from_IWMSyncReader2(iface); - FIXME("(%p)->(%d %p): stub!\n", This, stream_num, compressed); - return E_NOTIMPL; -} - -static HRESULT WINAPI WMSyncReader_GetStreamNumberForOutput(IWMSyncReader2 *iface, - DWORD output, WORD *stream_number) -{ - struct sync_reader *reader = impl_from_IWMSyncReader2(iface); - - TRACE("reader %p, output %lu, stream_number %p.\n", reader, output, stream_number); - - *stream_number = output + 1; - return S_OK; -} - -static HRESULT WINAPI WMSyncReader_GetStreamSelected(IWMSyncReader2 *iface, - WORD stream_number, WMT_STREAM_SELECTION *selection) -{ - struct sync_reader *reader = impl_from_IWMSyncReader2(iface); - - TRACE("reader %p, stream_number %u, selection %p.\n", reader, stream_number, selection); - - return wm_reader_get_stream_selection(&reader->reader, stream_number, selection); -} - -static HRESULT WINAPI WMSyncReader_Open(IWMSyncReader2 *iface, const WCHAR *filename) -{ - struct sync_reader *reader = impl_from_IWMSyncReader2(iface); - - TRACE("reader %p, filename %s.\n", reader, debugstr_w(filename)); - - return wm_reader_open_file(&reader->reader, filename); -} - -static HRESULT WINAPI WMSyncReader_OpenStream(IWMSyncReader2 *iface, IStream *stream) -{ - struct sync_reader *reader = impl_from_IWMSyncReader2(iface); - - TRACE("reader %p, stream %p.\n", reader, stream); - - return wm_reader_open_stream(&reader->reader, stream); -} - -static HRESULT WINAPI WMSyncReader_SetOutputProps(IWMSyncReader2 *iface, DWORD output, IWMOutputMediaProps *props) -{ - struct sync_reader *reader = impl_from_IWMSyncReader2(iface); - - TRACE("reader %p, output %lu, props %p.\n", reader, output, props); - - return wm_reader_set_output_props(&reader->reader, output, props); -} - -static HRESULT WINAPI WMSyncReader_SetOutputSetting(IWMSyncReader2 *iface, DWORD output, - const WCHAR *name, WMT_ATTR_DATATYPE type, const BYTE *value, WORD size) -{ - struct sync_reader *reader = impl_from_IWMSyncReader2(iface); - - TRACE("reader %p, output %lu, name %s, type %#x, value %p, size %u.\n", - reader, output, debugstr_w(name), type, value, size); - - if (!wcscmp(name, L"VideoSampleDurations")) - { - FIXME("Ignoring VideoSampleDurations setting.\n"); - return S_OK; - } - if (!wcscmp(name, L"EnableDiscreteOutput")) - { - FIXME("Ignoring EnableDiscreteOutput setting.\n"); - return S_OK; - } - if (!wcscmp(name, L"SpeakerConfig")) - { - FIXME("Ignoring SpeakerConfig setting.\n"); - return S_OK; - } - else - { - FIXME("Unknown setting %s; returning E_NOTIMPL.\n", debugstr_w(name)); - return E_NOTIMPL; - } -} - -static HRESULT WINAPI WMSyncReader_SetRange(IWMSyncReader2 *iface, QWORD start, LONGLONG duration) -{ - struct sync_reader *reader = impl_from_IWMSyncReader2(iface); - - TRACE("reader %p, start %I64u, duration %I64d.\n", reader, start, duration); - - wm_reader_seek(&reader->reader, start, duration); - return S_OK; -} - -static HRESULT WINAPI WMSyncReader_SetRangeByFrame(IWMSyncReader2 *iface, WORD stream_num, QWORD frame_num, - LONGLONG frames) -{ - struct sync_reader *This = impl_from_IWMSyncReader2(iface); - FIXME("(%p)->(%d %s %s): stub!\n", This, stream_num, wine_dbgstr_longlong(frame_num), wine_dbgstr_longlong(frames)); - return E_NOTIMPL; -} - -static HRESULT WINAPI WMSyncReader_SetReadStreamSamples(IWMSyncReader2 *iface, WORD stream_number, BOOL compressed) -{ - struct sync_reader *reader = impl_from_IWMSyncReader2(iface); - - TRACE("reader %p, stream_index %u, compressed %d.\n", reader, stream_number, compressed); - - return wm_reader_set_read_compressed(&reader->reader, stream_number, compressed); -} - -static HRESULT WINAPI WMSyncReader_SetStreamsSelected(IWMSyncReader2 *iface, - WORD count, WORD *stream_numbers, WMT_STREAM_SELECTION *selections) -{ - struct sync_reader *reader = impl_from_IWMSyncReader2(iface); - - TRACE("reader %p, count %u, stream_numbers %p, selections %p.\n", - reader, count, stream_numbers, selections); - - return wm_reader_set_streams_selected(&reader->reader, count, stream_numbers, selections); -} - -static HRESULT WINAPI WMSyncReader2_SetRangeByTimecode(IWMSyncReader2 *iface, WORD stream_num, - WMT_TIMECODE_EXTENSION_DATA *start, WMT_TIMECODE_EXTENSION_DATA *end) -{ - struct sync_reader *This = impl_from_IWMSyncReader2(iface); - FIXME("(%p)->(%u %p %p): stub!\n", This, stream_num, start, end); - return E_NOTIMPL; -} - -static HRESULT WINAPI WMSyncReader2_SetRangeByFrameEx(IWMSyncReader2 *iface, WORD stream_num, QWORD frame_num, - LONGLONG frames_to_read, QWORD *starttime) -{ - struct sync_reader *This = impl_from_IWMSyncReader2(iface); - FIXME("(%p)->(%u %s %s %p): stub!\n", This, stream_num, wine_dbgstr_longlong(frame_num), - wine_dbgstr_longlong(frames_to_read), starttime); - return E_NOTIMPL; -} - -static HRESULT WINAPI WMSyncReader2_SetAllocateForOutput(IWMSyncReader2 *iface, DWORD output_num, IWMReaderAllocatorEx *allocator) -{ - struct sync_reader *This = impl_from_IWMSyncReader2(iface); - FIXME("(%p)->(%lu %p): stub!\n", This, output_num, allocator); - return E_NOTIMPL; -} - -static HRESULT WINAPI WMSyncReader2_GetAllocateForOutput(IWMSyncReader2 *iface, DWORD output_num, IWMReaderAllocatorEx **allocator) -{ - struct sync_reader *This = impl_from_IWMSyncReader2(iface); - FIXME("(%p)->(%lu %p): stub!\n", This, output_num, allocator); - return E_NOTIMPL; -} - -static HRESULT WINAPI WMSyncReader2_SetAllocateForStream(IWMSyncReader2 *iface, DWORD stream_num, IWMReaderAllocatorEx *allocator) -{ - struct sync_reader *This = impl_from_IWMSyncReader2(iface); - FIXME("(%p)->(%lu %p): stub!\n", This, stream_num, allocator); - return E_NOTIMPL; -} - -static HRESULT WINAPI WMSyncReader2_GetAllocateForStream(IWMSyncReader2 *iface, DWORD stream_num, IWMReaderAllocatorEx **allocator) -{ - struct sync_reader *This = impl_from_IWMSyncReader2(iface); - FIXME("(%p)->(%lu %p): stub!\n", This, stream_num, allocator); - return E_NOTIMPL; -} - -static const IWMSyncReader2Vtbl WMSyncReader2Vtbl = { - WMSyncReader_QueryInterface, - WMSyncReader_AddRef, - WMSyncReader_Release, - WMSyncReader_Open, - WMSyncReader_Close, - WMSyncReader_SetRange, - WMSyncReader_SetRangeByFrame, - WMSyncReader_GetNextSample, - WMSyncReader_SetStreamsSelected, - WMSyncReader_GetStreamSelected, - WMSyncReader_SetReadStreamSamples, - WMSyncReader_GetReadStreamSamples, - WMSyncReader_GetOutputSetting, - WMSyncReader_SetOutputSetting, - WMSyncReader_GetOutputCount, - WMSyncReader_GetOutputProps, - WMSyncReader_SetOutputProps, - WMSyncReader_GetOutputFormatCount, - WMSyncReader_GetOutputFormat, - WMSyncReader_GetOutputNumberForStream, - WMSyncReader_GetStreamNumberForOutput, - WMSyncReader_GetMaxOutputSampleSize, - WMSyncReader_GetMaxStreamSampleSize, - WMSyncReader_OpenStream, - WMSyncReader2_SetRangeByTimecode, - WMSyncReader2_SetRangeByFrameEx, - WMSyncReader2_SetAllocateForOutput, - WMSyncReader2_GetAllocateForOutput, - WMSyncReader2_SetAllocateForStream, - WMSyncReader2_GetAllocateForStream -}; - -struct wm_reader *wm_reader_from_sync_reader_inner(IUnknown *iface) -{ - struct sync_reader *reader = impl_from_IUnknown(iface); - return &reader->reader; -} - -HRESULT WINAPI winegstreamer_create_wm_sync_reader(IUnknown *outer, void **out) -{ - struct sync_reader *object; - - TRACE("out %p.\n", out); - - if (!(object = calloc(1, sizeof(*object)))) - return E_OUTOFMEMORY; - - object->IUnknown_inner.lpVtbl = &unknown_inner_vtbl; - object->IWMSyncReader2_iface.lpVtbl = &WMSyncReader2Vtbl; - wm_reader_init(outer ? outer : &object->IUnknown_inner, &object->reader); - object->refcount = 1; - - TRACE("Created sync reader %p.\n", object); - *out = outer ? (void *)&object->IUnknown_inner : (void *)&object->IWMSyncReader2_iface; - return S_OK; -}
This merge request was approved by Zebediah Figura.