winegstreamer: Wrap callback in a IWMReaderAllocatorEx in the async reader.

This commit is contained in:
Rémi Bernon 2022-08-22 15:44:48 +02:00 committed by Alexandre Julliard
parent c185b5a966
commit 18b1959749

View file

@ -70,6 +70,7 @@ struct async_reader
CRITICAL_SECTION cs;
IWMReaderCallbackAdvanced *callback_advanced;
IWMReaderAllocatorEx *allocator;
IWMReaderCallback *callback;
void *context;
@ -87,6 +88,125 @@ struct async_reader
QWORD user_time;
};
struct allocator
{
IWMReaderAllocatorEx IWMReaderAllocatorEx_iface;
LONG refcount;
IWMReaderCallbackAdvanced *callback;
};
static struct allocator *impl_from_IWMReaderAllocatorEx(IWMReaderAllocatorEx *iface)
{
return CONTAINING_RECORD(iface, struct allocator, IWMReaderAllocatorEx_iface);
}
static HRESULT WINAPI allocator_QueryInterface(IWMReaderAllocatorEx *iface, REFIID iid, void **out)
{
struct allocator *allocator = impl_from_IWMReaderAllocatorEx(iface);
TRACE("iface %p, iid %s, out %p.\n", iface, debugstr_guid(iid), out);
if (IsEqualIID(iid, &IID_IUnknown)
|| IsEqualIID(iid, &IID_IWMReaderAllocatorEx))
*out = &allocator->IWMReaderAllocatorEx_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 allocator_AddRef(IWMReaderAllocatorEx *iface)
{
struct allocator *allocator = impl_from_IWMReaderAllocatorEx(iface);
ULONG refcount = InterlockedIncrement(&allocator->refcount);
TRACE("iface %p increasing refcount to %lu.\n", iface, refcount);
return refcount;
}
static ULONG WINAPI allocator_Release(IWMReaderAllocatorEx *iface)
{
struct allocator *allocator = impl_from_IWMReaderAllocatorEx(iface);
ULONG refcount = InterlockedDecrement(&allocator->refcount);
TRACE("iface %p decreasing refcount to %lu.\n", iface, refcount);
if (!refcount)
{
if (allocator->callback)
IWMReaderCallbackAdvanced_Release(allocator->callback);
free(allocator);
}
return refcount;
}
static HRESULT WINAPI allocator_AllocateForStreamEx(IWMReaderAllocatorEx *iface,
WORD stream_number, DWORD size, INSSBuffer **sample, DWORD flags,
QWORD pts, QWORD duration, void *context)
{
struct allocator *allocator = impl_from_IWMReaderAllocatorEx(iface);
TRACE("iface %p, stream_number %u, size %#lx, sample %p, flags %#lx, pts %I64d, duration %I64d, context %p.\n",
iface, stream_number, size, sample, flags, pts, duration, context);
if (allocator->callback)
return IWMReaderCallbackAdvanced_AllocateForStream(allocator->callback,
stream_number, size, sample, context);
return E_NOTIMPL;
}
static HRESULT WINAPI allocator_AllocateForOutputEx(IWMReaderAllocatorEx *iface,
DWORD output, DWORD size, INSSBuffer **sample, DWORD flags,
QWORD pts, QWORD duration, void *context)
{
struct allocator *allocator = impl_from_IWMReaderAllocatorEx(iface);
TRACE("iface %p, output %lu, size %#lx, sample %p, flags %#lx, pts %I64d, duration %I64d, context %p.\n",
iface, output, size, sample, flags, pts, duration, context);
if (allocator->callback)
return IWMReaderCallbackAdvanced_AllocateForOutput(allocator->callback,
output, size, sample, context);
return E_NOTIMPL;
}
static const IWMReaderAllocatorExVtbl allocator_vtbl =
{
allocator_QueryInterface,
allocator_AddRef,
allocator_Release,
allocator_AllocateForStreamEx,
allocator_AllocateForOutputEx,
};
static HRESULT allocator_create(IWMReaderCallback *callback, IWMReaderAllocatorEx **out)
{
struct allocator *allocator;
HRESULT hr;
if (!(allocator = calloc(1, sizeof(*allocator))))
return E_OUTOFMEMORY;
allocator->IWMReaderAllocatorEx_iface.lpVtbl = &allocator_vtbl;
allocator->refcount = 1;
if (FAILED(hr = IWMReaderCallback_QueryInterface(callback,
&IID_IWMReaderCallbackAdvanced, (void **)&allocator->callback)))
{
WARN("Failed to retrieve IWMReaderCallbackAdvanced interface, hr %#lx\n", hr);
allocator->callback = NULL;
}
*out = &allocator->IWMReaderAllocatorEx_iface;
return S_OK;
}
static REFERENCE_TIME get_current_time(const struct async_reader *reader)
{
LARGE_INTEGER time;
@ -306,6 +426,10 @@ static void async_reader_close(struct async_reader *reader)
free(op);
}
if (reader->allocator)
IWMReaderAllocatorEx_Release(reader->allocator);
reader->allocator = NULL;
if (reader->callback_advanced)
IWMReaderCallbackAdvanced_Release(reader->callback_advanced);
reader->callback_advanced = NULL;
@ -323,6 +447,9 @@ static HRESULT async_reader_open(struct async_reader *reader, IWMReaderCallback
IWMReaderCallback_AddRef((reader->callback = callback));
reader->context = context;
if (FAILED(hr = allocator_create(reader->callback, &reader->allocator)))
goto error;
if (FAILED(hr = IWMReaderCallback_QueryInterface(callback, &IID_IWMReaderCallbackAdvanced,
(void **)&reader->callback_advanced)))
{