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;