[PATCH 3/7] mf: Improve ShutdownObject() behavior for sample grabber activation object.
Nikolay Sivov
nsivov at codeweavers.com
Wed Mar 11 06:19:41 CDT 2020
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/mf/main.c | 23 +++++++-
dlls/mf/mf_private.h | 1 +
dlls/mf/samplegrabber.c | 11 ++++
dlls/mf/sar.c | 6 ++
dlls/mf/tests/mf.c | 122 +++++++++++++++++++++++++++++++++++++++-
5 files changed, 158 insertions(+), 5 deletions(-)
diff --git a/dlls/mf/main.c b/dlls/mf/main.c
index f16e3e8aba..ecf7de23b6 100644
--- a/dlls/mf/main.c
+++ b/dlls/mf/main.c
@@ -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);
}
diff --git a/dlls/mf/mf_private.h b/dlls/mf/mf_private.h
index 0b7d1c65fa..f68c7d8d4c 100644
--- a/dlls/mf/mf_private.h
+++ b/dlls/mf/mf_private.h
@@ -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);
};
diff --git a/dlls/mf/samplegrabber.c b/dlls/mf/samplegrabber.c
index 82febf236d..ea0d596f7e 100644
--- a/dlls/mf/samplegrabber.c
+++ b/dlls/mf/samplegrabber.c
@@ -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,
};
diff --git a/dlls/mf/sar.c b/dlls/mf/sar.c
index c0c1803df1..4f20472748 100644
--- a/dlls/mf/sar.c
+++ b/dlls/mf/sar.c
@@ -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,
};
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index 0593ed8868..5742da1620 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -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)
--
2.25.1
More information about the wine-devel
mailing list