Skip to content
Snippets Groups Projects
Commit efb369f5 authored by Conor McCarthy's avatar Conor McCarthy Committed by Alexandre Julliard
Browse files

winegstreamer: Send media source shutdown notification via IMFMediaShutdownNotify.

parent a7d5b7f5
No related branches found
No related tags found
No related merge requests found
......@@ -174,12 +174,15 @@ struct media_source
IMFGetService IMFGetService_iface;
IMFRateSupport IMFRateSupport_iface;
IMFRateControl IMFRateControl_iface;
IMFMediaShutdownNotify IMFMediaShutdownNotify_iface;
IMFAsyncCallback async_commands_callback;
LONG ref;
DWORD async_commands_queue;
IMFMediaEventQueue *event_queue;
IMFByteStream *byte_stream;
IMFAsyncResult *shutdown_result;
CRITICAL_SECTION cs;
UINT64 file_size;
......@@ -229,6 +232,11 @@ static inline struct media_source *impl_from_IMFRateControl(IMFRateControl *ifac
return CONTAINING_RECORD(iface, struct media_source, IMFRateControl_iface);
}
static inline struct media_source *impl_from_IMFMediaShutdownNotify(IMFMediaShutdownNotify *iface)
{
return CONTAINING_RECORD(iface, struct media_source, IMFMediaShutdownNotify_iface);
}
static inline struct media_source *impl_from_async_commands_callback_IMFAsyncCallback(IMFAsyncCallback *iface)
{
return CONTAINING_RECORD(iface, struct media_source, async_commands_callback);
......@@ -1315,6 +1323,76 @@ static const IMFRateControlVtbl media_source_rate_control_vtbl =
media_source_rate_control_GetRate,
};
static void media_source_release_shutdown_callback(struct media_source *source)
{
if (source->shutdown_result)
IMFAsyncResult_Release(source->shutdown_result);
source->shutdown_result = NULL;
}
static HRESULT WINAPI media_source_shutdown_notify_QueryInterface(IMFMediaShutdownNotify *iface, REFIID riid, void **obj)
{
if (IsEqualIID(riid, &IID_IMFMediaShutdownNotify) ||
IsEqualIID(riid, &IID_IUnknown))
{
*obj = iface;
IUnknown_AddRef(iface);
return S_OK;
}
WARN("Unsupported %s.\n", debugstr_guid(riid));
*obj = NULL;
return E_NOINTERFACE;
}
static ULONG WINAPI media_source_shutdown_notify_AddRef(IMFMediaShutdownNotify *iface)
{
struct media_source *source = impl_from_IMFMediaShutdownNotify(iface);
return IMFMediaSource_AddRef(&source->IMFMediaSource_iface);
}
static ULONG WINAPI media_source_shutdown_notify_Release(IMFMediaShutdownNotify *iface)
{
struct media_source *source = impl_from_IMFMediaShutdownNotify(iface);
return IMFMediaSource_Release(&source->IMFMediaSource_iface);
}
static HRESULT WINAPI media_source_shutdown_notify_set_notification_callback(IMFMediaShutdownNotify *iface,
IMFAsyncCallback *callback, IUnknown *state)
{
struct media_source *source = impl_from_IMFMediaShutdownNotify(iface);
IMFAsyncResult *result = NULL;
HRESULT hr = S_OK;
EnterCriticalSection(&source->cs);
if (source->state == SOURCE_SHUTDOWN)
hr = MF_E_SHUTDOWN;
else
{
if (callback && FAILED(hr = MFCreateAsyncResult(NULL, callback, state, &result)))
{
LeaveCriticalSection(&source->cs);
return hr;
}
media_source_release_shutdown_callback(source);
source->shutdown_result = result;
}
LeaveCriticalSection(&source->cs);
return hr;
}
static const IMFMediaShutdownNotifyVtbl media_source_shutdown_notify_vtbl =
{
media_source_shutdown_notify_QueryInterface,
media_source_shutdown_notify_AddRef,
media_source_shutdown_notify_Release,
media_source_shutdown_notify_set_notification_callback,
};
static HRESULT WINAPI media_source_QueryInterface(IMFMediaSource *iface, REFIID riid, void **out)
{
struct media_source *source = impl_from_IMFMediaSource(iface);
......@@ -1331,6 +1409,10 @@ static HRESULT WINAPI media_source_QueryInterface(IMFMediaSource *iface, REFIID
{
*out = &source->IMFGetService_iface;
}
else if (IsEqualIID(riid, &IID_IMFMediaShutdownNotify))
{
*out = &source->IMFMediaShutdownNotify_iface;
}
else
{
FIXME("%s, %p.\n", debugstr_guid(riid), out);
......@@ -1361,6 +1443,7 @@ static ULONG WINAPI media_source_Release(IMFMediaSource *iface)
if (!ref)
{
media_source_release_shutdown_callback(source);
IMFMediaSource_Shutdown(iface);
IMFMediaEventQueue_Release(source->event_queue);
IMFByteStream_Release(source->byte_stream);
......@@ -1543,6 +1626,7 @@ static HRESULT WINAPI media_source_Pause(IMFMediaSource *iface)
static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface)
{
struct media_source *source = impl_from_IMFMediaSource(iface);
HRESULT hr;
TRACE("%p.\n", iface);
......@@ -1575,6 +1659,13 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface)
free(source->descriptors);
free(source->streams);
if (source->shutdown_result)
{
if (FAILED(hr = MFPutWorkItemEx(MFASYNC_CALLBACK_QUEUE_STANDARD, source->shutdown_result)))
WARN("Failed to put shutdown notification, hr %#lx.\n", hr);
media_source_release_shutdown_callback(source);
}
LeaveCriticalSection(&source->cs);
MFUnlockWorkQueue(source->async_commands_queue);
......@@ -1633,6 +1724,7 @@ static HRESULT media_source_create(struct object_context *context, IMFMediaSourc
object->IMFGetService_iface.lpVtbl = &media_source_get_service_vtbl;
object->IMFRateSupport_iface.lpVtbl = &media_source_rate_support_vtbl;
object->IMFRateControl_iface.lpVtbl = &media_source_rate_control_vtbl;
object->IMFMediaShutdownNotify_iface.lpVtbl = &media_source_shutdown_notify_vtbl;
object->async_commands_callback.lpVtbl = &source_async_commands_callback_vtbl;
object->ref = 1;
object->byte_stream = context->stream;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment