evr/presenter: Add sample allocator notification callback.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
38d75c4294
commit
03a10db214
|
@ -66,6 +66,7 @@ struct video_presenter
|
||||||
IMFRateSupport IMFRateSupport_iface;
|
IMFRateSupport IMFRateSupport_iface;
|
||||||
IMFGetService IMFGetService_iface;
|
IMFGetService IMFGetService_iface;
|
||||||
IMFVideoPositionMapper IMFVideoPositionMapper_iface;
|
IMFVideoPositionMapper IMFVideoPositionMapper_iface;
|
||||||
|
IMFVideoSampleAllocatorNotify allocator_cb;
|
||||||
IUnknown IUnknown_inner;
|
IUnknown IUnknown_inner;
|
||||||
IUnknown *outer_unk;
|
IUnknown *outer_unk;
|
||||||
LONG refcount;
|
LONG refcount;
|
||||||
|
@ -131,6 +132,11 @@ static struct video_presenter *impl_from_IMFVideoPositionMapper(IMFVideoPosition
|
||||||
return CONTAINING_RECORD(iface, struct video_presenter, IMFVideoPositionMapper_iface);
|
return CONTAINING_RECORD(iface, struct video_presenter, IMFVideoPositionMapper_iface);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct video_presenter *impl_from_IMFVideoSampleAllocatorNotify(IMFVideoSampleAllocatorNotify *iface)
|
||||||
|
{
|
||||||
|
return CONTAINING_RECORD(iface, struct video_presenter, allocator_cb);
|
||||||
|
}
|
||||||
|
|
||||||
static void video_presenter_notify_renderer(struct video_presenter *presenter,
|
static void video_presenter_notify_renderer(struct video_presenter *presenter,
|
||||||
LONG event, LONG_PTR param1, LONG_PTR param2)
|
LONG event, LONG_PTR param1, LONG_PTR param2)
|
||||||
{
|
{
|
||||||
|
@ -183,6 +189,18 @@ static void video_presenter_get_native_video_size(struct video_presenter *presen
|
||||||
IMFMediaType_Release(media_type);
|
IMFMediaType_Release(media_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* It is important this is called to reset callback too to break circular referencing,
|
||||||
|
when allocator keeps a reference of its container, that created it. */
|
||||||
|
static void video_presenter_set_allocator_callback(struct video_presenter *presenter,
|
||||||
|
IMFVideoSampleAllocatorNotify *notify_cb)
|
||||||
|
{
|
||||||
|
IMFVideoSampleAllocatorCallback *cb;
|
||||||
|
|
||||||
|
IMFVideoSampleAllocator_QueryInterface(presenter->allocator, &IID_IMFVideoSampleAllocatorCallback, (void **)&cb);
|
||||||
|
IMFVideoSampleAllocatorCallback_SetCallback(cb, notify_cb);
|
||||||
|
IMFVideoSampleAllocatorCallback_Release(cb);
|
||||||
|
}
|
||||||
|
|
||||||
static void video_presenter_reset_media_type(struct video_presenter *presenter)
|
static void video_presenter_reset_media_type(struct video_presenter *presenter)
|
||||||
{
|
{
|
||||||
if (presenter->media_type)
|
if (presenter->media_type)
|
||||||
|
@ -190,6 +208,7 @@ static void video_presenter_reset_media_type(struct video_presenter *presenter)
|
||||||
presenter->media_type = NULL;
|
presenter->media_type = NULL;
|
||||||
|
|
||||||
IMFVideoSampleAllocator_UninitializeSampleAllocator(presenter->allocator);
|
IMFVideoSampleAllocator_UninitializeSampleAllocator(presenter->allocator);
|
||||||
|
video_presenter_set_allocator_callback(presenter, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
static HRESULT video_presenter_set_media_type(struct video_presenter *presenter, IMFMediaType *media_type)
|
static HRESULT video_presenter_set_media_type(struct video_presenter *presenter, IMFMediaType *media_type)
|
||||||
|
@ -298,6 +317,8 @@ static HRESULT video_presenter_start_streaming(struct video_presenter *presenter
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
video_presenter_set_allocator_callback(presenter, &presenter->allocator_cb);
|
||||||
|
|
||||||
WaitForSingleObject(presenter->thread.ready_event, INFINITE);
|
WaitForSingleObject(presenter->thread.ready_event, INFINITE);
|
||||||
CloseHandle(presenter->thread.ready_event);
|
CloseHandle(presenter->thread.ready_event);
|
||||||
presenter->thread.ready_event = NULL;
|
presenter->thread.ready_event = NULL;
|
||||||
|
@ -320,6 +341,7 @@ static HRESULT video_presenter_end_streaming(struct video_presenter *presenter)
|
||||||
TRACE("Terminated streaming thread tid %#x.\n", presenter->thread.tid);
|
TRACE("Terminated streaming thread tid %#x.\n", presenter->thread.tid);
|
||||||
|
|
||||||
memset(&presenter->thread, 0, sizeof(presenter->thread));
|
memset(&presenter->thread, 0, sizeof(presenter->thread));
|
||||||
|
video_presenter_set_allocator_callback(presenter, NULL);
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -1222,6 +1244,47 @@ static const IMFVideoPositionMapperVtbl video_presenter_position_mapper_vtbl =
|
||||||
video_presenter_position_mapper_MapOutputCoordinateToInputStream,
|
video_presenter_position_mapper_MapOutputCoordinateToInputStream,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static HRESULT WINAPI video_presenter_allocator_cb_QueryInterface(IMFVideoSampleAllocatorNotify *iface,
|
||||||
|
REFIID riid, void **obj)
|
||||||
|
{
|
||||||
|
if (IsEqualIID(riid, &IID_IMFVideoSampleAllocatorNotify) ||
|
||||||
|
IsEqualIID(riid, &IID_IUnknown))
|
||||||
|
{
|
||||||
|
*obj = iface;
|
||||||
|
IMFVideoSampleAllocatorNotify_AddRef(iface);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
WARN("Unsupported interface %s.\n", debugstr_guid(riid));
|
||||||
|
*obj = NULL;
|
||||||
|
return E_NOINTERFACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI video_presenter_allocator_cb_AddRef(IMFVideoSampleAllocatorNotify *iface)
|
||||||
|
{
|
||||||
|
struct video_presenter *presenter = impl_from_IMFVideoSampleAllocatorNotify(iface);
|
||||||
|
return IMFVideoPresenter_AddRef(&presenter->IMFVideoPresenter_iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static ULONG WINAPI video_presenter_allocator_cb_Release(IMFVideoSampleAllocatorNotify *iface)
|
||||||
|
{
|
||||||
|
struct video_presenter *presenter = impl_from_IMFVideoSampleAllocatorNotify(iface);
|
||||||
|
return IMFVideoPresenter_Release(&presenter->IMFVideoPresenter_iface);
|
||||||
|
}
|
||||||
|
|
||||||
|
static HRESULT WINAPI video_presenter_allocator_cb_NotifyRelease(IMFVideoSampleAllocatorNotify *iface)
|
||||||
|
{
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IMFVideoSampleAllocatorNotifyVtbl video_presenter_allocator_cb_vtbl =
|
||||||
|
{
|
||||||
|
video_presenter_allocator_cb_QueryInterface,
|
||||||
|
video_presenter_allocator_cb_AddRef,
|
||||||
|
video_presenter_allocator_cb_Release,
|
||||||
|
video_presenter_allocator_cb_NotifyRelease,
|
||||||
|
};
|
||||||
|
|
||||||
HRESULT WINAPI MFCreateVideoPresenter(IUnknown *owner, REFIID riid_device, REFIID riid, void **obj)
|
HRESULT WINAPI MFCreateVideoPresenter(IUnknown *owner, REFIID riid_device, REFIID riid, void **obj)
|
||||||
{
|
{
|
||||||
TRACE("%p, %s, %s, %p.\n", owner, debugstr_guid(riid_device), debugstr_guid(riid), obj);
|
TRACE("%p, %s, %s, %p.\n", owner, debugstr_guid(riid_device), debugstr_guid(riid), obj);
|
||||||
|
@ -1290,6 +1353,7 @@ HRESULT evr_presenter_create(IUnknown *outer, void **out)
|
||||||
object->IMFRateSupport_iface.lpVtbl = &video_presenter_rate_support_vtbl;
|
object->IMFRateSupport_iface.lpVtbl = &video_presenter_rate_support_vtbl;
|
||||||
object->IMFGetService_iface.lpVtbl = &video_presenter_getservice_vtbl;
|
object->IMFGetService_iface.lpVtbl = &video_presenter_getservice_vtbl;
|
||||||
object->IMFVideoPositionMapper_iface.lpVtbl = &video_presenter_position_mapper_vtbl;
|
object->IMFVideoPositionMapper_iface.lpVtbl = &video_presenter_position_mapper_vtbl;
|
||||||
|
object->allocator_cb.lpVtbl = &video_presenter_allocator_cb_vtbl;
|
||||||
object->IUnknown_inner.lpVtbl = &video_presenter_inner_vtbl;
|
object->IUnknown_inner.lpVtbl = &video_presenter_inner_vtbl;
|
||||||
object->outer_unk = outer ? outer : &object->IUnknown_inner;
|
object->outer_unk = outer ? outer : &object->IUnknown_inner;
|
||||||
object->refcount = 1;
|
object->refcount = 1;
|
||||||
|
|
Loading…
Reference in New Issue