mf: Improve ShutdownObject() behavior for sample grabber activation object.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2020-03-11 14:19:41 +03:00 committed by Alexandre Julliard
parent 2062dd95d7
commit 15657f68a4
5 changed files with 158 additions and 5 deletions

View File

@ -402,14 +402,23 @@ static HRESULT WINAPI activate_object_ActivateObject(IMFActivate *iface, REFIID
static HRESULT WINAPI activate_object_ShutdownObject(IMFActivate *iface)
{
FIXME("%p.\n", iface);
struct activate_object *activate = impl_from_IMFActivate(iface);
IUnknown *object;
return E_NOTIMPL;
TRACE("%p.\n", iface);
if ((object = InterlockedCompareExchangePointer((void **)&activate->object, NULL, activate->object)))
{
activate->funcs->shutdown_object(activate->context, object);
IUnknown_Release(object);
}
return S_OK;
}
static HRESULT WINAPI activate_object_DetachObject(IMFActivate *iface)
{
FIXME("%p.\n", iface);
TRACE("%p.\n", iface);
return E_NOTIMPL;
}
@ -1265,6 +1274,10 @@ static HRESULT evr_create_object(IMFAttributes *attributes, void *user_context,
return E_NOTIMPL;
}
static void evr_shutdown_object(void *user_context, IUnknown *obj)
{
}
static void evr_free_private(void *user_context)
{
}
@ -1272,6 +1285,7 @@ static void evr_free_private(void *user_context)
static const struct activate_funcs evr_activate_funcs =
{
evr_create_object,
evr_shutdown_object,
evr_free_private,
};
@ -1279,6 +1293,9 @@ HRESULT WINAPI MFCreateVideoRendererActivate(HWND hwnd, IMFActivate **activate)
{
TRACE("%p, %p.\n", hwnd, activate);
if (!activate)
return E_POINTER;
return create_activation_object(hwnd, &evr_activate_funcs, activate);
}

View File

@ -50,6 +50,7 @@ static inline BOOL mf_array_reserve(void **elements, size_t *capacity, size_t co
struct activate_funcs
{
HRESULT (*create_object)(IMFAttributes *attributes, void *context, IUnknown **object);
void (*shutdown_object)(void *context, IUnknown *object);
void (*free_private)(void *context);
};

View File

@ -101,6 +101,7 @@ struct sample_grabber_activate_context
{
IMFMediaType *media_type;
IMFSampleGrabberSinkCallback *callback;
BOOL shut_down;
};
static void sample_grabber_free_private(void *user_context)
@ -1320,6 +1321,9 @@ static HRESULT sample_grabber_create_object(IMFAttributes *attributes, void *use
TRACE("%p, %p, %p.\n", attributes, user_context, obj);
if (context->shut_down)
return MF_E_SHUTDOWN;
/* At least major type is required. */
if (FAILED(IMFMediaType_GetMajorType(context->media_type, &guid)))
return MF_E_INVALIDMEDIATYPE;
@ -1363,9 +1367,16 @@ failed:
return hr;
}
static void sample_grabber_shutdown_object(void *user_context, IUnknown *obj)
{
struct sample_grabber_activate_context *context = user_context;
context->shut_down = TRUE;
}
static const struct activate_funcs sample_grabber_activate_funcs =
{
sample_grabber_create_object,
sample_grabber_shutdown_object,
sample_grabber_free_private,
};

View File

@ -33,6 +33,11 @@ static HRESULT sar_create_object(IMFAttributes *attributes, void *user_context,
return E_NOTIMPL;
}
static void sar_shutdown_object(void *user_context, IUnknown *obj)
{
/* FIXME: shut down sink */
}
static void sar_free_private(void *user_context)
{
}
@ -40,6 +45,7 @@ static void sar_free_private(void *user_context)
static const struct activate_funcs sar_activate_funcs =
{
sar_create_object,
sar_shutdown_object,
sar_free_private,
};

View File

@ -2044,10 +2044,15 @@ static void test_sample_grabber(void)
IMFPresentationClock_Release(clock);
hr = IMFMediaSink_GetCharacteristics(sink, &flags);
ok(hr == S_OK, "Failed to get sink flags, hr %#x.\n", hr);
hr = IMFActivate_ShutdownObject(activate);
todo_wine
ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
hr = IMFMediaSink_GetCharacteristics(sink, &flags);
ok(hr == S_OK, "Failed to get sink flags, hr %#x.\n", hr);
hr = IMFStreamSink_GetMediaTypeHandler(stream, &handler);
ok(hr == S_OK, "Failed to get type handler, hr %#x.\n", hr);
@ -2240,8 +2245,36 @@ todo_wine
ok(hr == S_OK, "Failed to get sink flags, hr %#x.\n", hr);
ok(flags & MEDIASINK_RATELESS, "Unexpected flags %#x.\n", flags);
hr = IMFActivate_ShutdownObject(activate);
ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
hr = IMFMediaSink_Shutdown(sink);
ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
IMFMediaSink_Release(sink);
/* Detaching */
hr = MFCreateSampleGrabberSinkActivate(media_type, &grabber_callback, &activate);
ok(hr == S_OK, "Failed to create grabber activate, hr %#x.\n", hr);
hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
ok(hr == S_OK, "Failed to activate object, hr %#x.\n", hr);
IMFMediaSink_Release(sink);
hr = IMFActivate_ShutdownObject(activate);
ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
hr = IMFActivate_GetCount(activate, &count);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
hr = IMFActivate_DetachObject(activate);
ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
IMFActivate_Release(activate);
IMFMediaType_Release(media_type);
hr = MFShutdown();
@ -2608,8 +2641,9 @@ static void test_sar(void)
{
IMFPresentationTimeSource *time_source;
IMFClockStateSink *state_sink;
IMFMediaSink *sink, *sink2;
IMFActivate *activate;
MFCLOCK_STATE state;
IMFMediaSink *sink;
IMFClock *clock;
DWORD flags;
HRESULT hr;
@ -2656,19 +2690,103 @@ if (SUCCEEDED(hr))
IMFMediaSink_Release(sink);
}
/* Activation */
hr = MFCreateAudioRendererActivate(&activate);
ok(hr == S_OK, "Failed to create activation object, hr %#x.\n", hr);
hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
todo_wine
ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
if (hr == S_OK)
{
hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink2);
ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
ok(sink == sink2, "Unexpected instance.\n");
IMFMediaSink_Release(sink2);
hr = IMFMediaSink_GetCharacteristics(sink, &flags);
ok(hr == S_OK, "Failed to get sink flags, hr %#x.\n", hr);
hr = IMFActivate_ShutdownObject(activate);
ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
hr = IMFMediaSink_GetCharacteristics(sink, &flags);
ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
IMFMediaSink_Release(sink);
hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
hr = IMFMediaSink_GetCharacteristics(sink, &flags);
ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
IMFMediaSink_Release(sink);
hr = IMFActivate_DetachObject(activate);
ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
}
IMFActivate_Release(activate);
CoUninitialize();
}
static void test_evr(void)
{
IMFMediaSink *sink, *sink2;
IMFActivate *activate;
DWORD flags;
HRESULT hr;
hr = CoInitialize(NULL);
ok(hr == S_OK, "Failed to initialize, hr %#x.\n", hr);
hr = MFCreateVideoRendererActivate(NULL, NULL);
ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr);
hr = MFCreateVideoRendererActivate(NULL, &activate);
ok(hr == S_OK, "Failed to create activate object, hr %#x.\n", hr);
hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
todo_wine
ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
if (hr == S_OK)
{
hr = IMFMediaSink_GetCharacteristics(sink, &flags);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
hr = IMFActivate_ShutdownObject(activate);
ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
hr = IMFMediaSink_GetCharacteristics(sink, &flags);
ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
/* Activate again. */
hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink2);
ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
ok(sink == sink2, "Unexpected instance.\n");
IMFMediaSink_Release(sink2);
hr = IMFActivate_DetachObject(activate);
ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
hr = IMFMediaSink_GetCharacteristics(sink, &flags);
ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink2);
ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
hr = IMFActivate_ShutdownObject(activate);
ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr);
IMFMediaSink_Release(sink2);
IMFMediaSink_Release(sink);
}
IMFActivate_Release(activate);
CoUninitialize();
}
static void test_MFCreateSimpleTypeHandler(void)