winegstreamer: Get rid of the wm_reader_ops callbacks.

Controlling lifetime from the sync / async reader side.
This commit is contained in:
Rémi Bernon 2022-09-16 07:56:20 +02:00 committed by Alexandre Julliard
parent 0f25fadb14
commit 131ada052a
4 changed files with 193 additions and 262 deletions

View file

@ -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);

View file

@ -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);
return IWMProfile3_Release(&reader->reader.IWMProfile3_iface);
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);
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");

View file

@ -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");

View file

@ -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);
return IWMProfile3_Release(&reader->reader.IWMProfile3_iface);
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 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;