Nikolay Sivov : mfplay: Add IPropertyStore support to media player object.
Alexandre Julliard
julliard at winehq.org
Mon Apr 5 16:28:24 CDT 2021
Module: wine
Branch: master
Commit: 6a389d14a6732c58183c9a82add7707d2e5bfce3
URL: https://source.winehq.org/git/wine.git/?a=commit;h=6a389d14a6732c58183c9a82add7707d2e5bfce3
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Mon Apr 5 09:10:59 2021 +0300
mfplay: Add IPropertyStore support to media player object.
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/mfplay/player.c | 120 ++++++++++++++++++++++++++++++++++++++++++---
dlls/mfplay/tests/mfplay.c | 36 ++++++++++++++
2 files changed, 148 insertions(+), 8 deletions(-)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c
index 0305f663924..e729a863da9 100644
--- a/dlls/mfplay/player.c
+++ b/dlls/mfplay/player.c
@@ -47,8 +47,10 @@ static void platform_shutdown(void)
struct media_player
{
IMFPMediaPlayer IMFPMediaPlayer_iface;
+ IPropertyStore IPropertyStore_iface;
LONG refcount;
IMFPMediaPlayerCallback *callback;
+ IPropertyStore *propstore;
};
static struct media_player *impl_from_IMFPMediaPlayer(IMFPMediaPlayer *iface)
@@ -56,22 +58,36 @@ static struct media_player *impl_from_IMFPMediaPlayer(IMFPMediaPlayer *iface)
return CONTAINING_RECORD(iface, struct media_player, IMFPMediaPlayer_iface);
}
+static struct media_player *impl_from_IPropertyStore(IPropertyStore *iface)
+{
+ return CONTAINING_RECORD(iface, struct media_player, IPropertyStore_iface);
+}
+
static HRESULT WINAPI media_player_QueryInterface(IMFPMediaPlayer *iface, REFIID riid, void **obj)
{
+ struct media_player *player = impl_from_IMFPMediaPlayer(iface);
+
TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
if (IsEqualIID(riid, &IID_IMFPMediaPlayer) ||
IsEqualIID(riid, &IID_IUnknown))
{
- *obj = iface;
- IMFPMediaPlayer_AddRef(iface);
- return S_OK;
+ *obj = &player->IMFPMediaPlayer_iface;
+ }
+ else if (IsEqualIID(riid, &IID_IPropertyStore))
+ {
+ *obj = &player->IPropertyStore_iface;
}
+ else
+ {
+ WARN("Unsupported interface %s.\n", debugstr_guid(riid));
+ *obj = NULL;
- WARN("Unsupported interface %s.\n", debugstr_guid(riid));
- *obj = NULL;
+ return E_NOINTERFACE;
+ }
- return E_NOINTERFACE;
+ IUnknown_AddRef((IUnknown *)*obj);
+ return S_OK;
}
static ULONG WINAPI media_player_AddRef(IMFPMediaPlayer *iface)
@@ -95,6 +111,8 @@ static ULONG WINAPI media_player_Release(IMFPMediaPlayer *iface)
{
if (player->callback)
IMFPMediaPlayerCallback_Release(player->callback);
+ if (player->propstore)
+ IPropertyStore_Release(player->propstore);
heap_free(player);
platform_shutdown();
@@ -406,25 +424,111 @@ static const IMFPMediaPlayerVtbl media_player_vtbl =
media_player_Shutdown,
};
+static HRESULT WINAPI media_player_propstore_QueryInterface(IPropertyStore *iface,
+ REFIID riid, void **obj)
+{
+ struct media_player *player = impl_from_IPropertyStore(iface);
+ return IMFPMediaPlayer_QueryInterface(&player->IMFPMediaPlayer_iface, riid, obj);
+}
+
+static ULONG WINAPI media_player_propstore_AddRef(IPropertyStore *iface)
+{
+ struct media_player *player = impl_from_IPropertyStore(iface);
+ return IMFPMediaPlayer_AddRef(&player->IMFPMediaPlayer_iface);
+}
+
+static ULONG WINAPI media_player_propstore_Release(IPropertyStore *iface)
+{
+ struct media_player *player = impl_from_IPropertyStore(iface);
+ return IMFPMediaPlayer_Release(&player->IMFPMediaPlayer_iface);
+}
+
+static HRESULT WINAPI media_player_propstore_GetCount(IPropertyStore *iface, DWORD *count)
+{
+ struct media_player *player = impl_from_IPropertyStore(iface);
+
+ TRACE("%p, %p.\n", iface, count);
+
+ return IPropertyStore_GetCount(player->propstore, count);
+}
+
+static HRESULT WINAPI media_player_propstore_GetAt(IPropertyStore *iface, DWORD prop, PROPERTYKEY *key)
+{
+ struct media_player *player = impl_from_IPropertyStore(iface);
+
+ TRACE("%p, %u, %p.\n", iface, prop, key);
+
+ return IPropertyStore_GetAt(player->propstore, prop, key);
+}
+
+static HRESULT WINAPI media_player_propstore_GetValue(IPropertyStore *iface, REFPROPERTYKEY key, PROPVARIANT *value)
+{
+ struct media_player *player = impl_from_IPropertyStore(iface);
+
+ TRACE("%p, %p, %p.\n", iface, key, value);
+
+ return IPropertyStore_GetValue(player->propstore, key, value);
+}
+
+static HRESULT WINAPI media_player_propstore_SetValue(IPropertyStore *iface, REFPROPERTYKEY key, REFPROPVARIANT value)
+{
+ struct media_player *player = impl_from_IPropertyStore(iface);
+
+ TRACE("%p, %p, %p.\n", iface, key, value);
+
+ return IPropertyStore_SetValue(player->propstore, key, value);
+}
+
+static HRESULT WINAPI media_player_propstore_Commit(IPropertyStore *iface)
+{
+ struct media_player *player = impl_from_IPropertyStore(iface);
+
+ TRACE("%p.\n", iface);
+
+ return IPropertyStore_Commit(player->propstore);
+}
+
+static const IPropertyStoreVtbl media_player_propstore_vtbl =
+{
+ media_player_propstore_QueryInterface,
+ media_player_propstore_AddRef,
+ media_player_propstore_Release,
+ media_player_propstore_GetCount,
+ media_player_propstore_GetAt,
+ media_player_propstore_GetValue,
+ media_player_propstore_SetValue,
+ media_player_propstore_Commit,
+};
+
HRESULT WINAPI MFPCreateMediaPlayer(const WCHAR *url, BOOL start_playback, MFP_CREATION_OPTIONS options,
IMFPMediaPlayerCallback *callback, HWND hwnd, IMFPMediaPlayer **player)
{
struct media_player *object;
+ HRESULT hr;
TRACE("%s, %d, %#x, %p, %p, %p.\n", debugstr_w(url), start_playback, options, callback, hwnd, player);
if (!(object = heap_alloc_zero(sizeof(*object))))
return E_OUTOFMEMORY;
+ platform_startup();
+
object->IMFPMediaPlayer_iface.lpVtbl = &media_player_vtbl;
+ object->IPropertyStore_iface.lpVtbl = &media_player_propstore_vtbl;
object->refcount = 1;
object->callback = callback;
if (object->callback)
IMFPMediaPlayerCallback_AddRef(object->callback);
-
- platform_startup();
+ if (FAILED(hr = CreatePropertyStore(&object->propstore)))
+ goto failed;
*player = &object->IMFPMediaPlayer_iface;
return S_OK;
+
+failed:
+
+ IMFPMediaPlayer_Release(&object->IMFPMediaPlayer_iface);
+
+ return hr;
}
diff --git a/dlls/mfplay/tests/mfplay.c b/dlls/mfplay/tests/mfplay.c
index ef8aaddc76f..64347265c40 100644
--- a/dlls/mfplay/tests/mfplay.c
+++ b/dlls/mfplay/tests/mfplay.c
@@ -26,6 +26,21 @@
#include "wine/test.h"
+#define check_interface(a, b, c) check_interface_(__LINE__, a, b, c)
+static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported)
+{
+ IUnknown *iface = iface_ptr;
+ HRESULT hr, expected_hr;
+ IUnknown *unk;
+
+ expected_hr = supported ? S_OK : E_NOINTERFACE;
+
+ hr = IUnknown_QueryInterface(iface, iid, (void **)&unk);
+ ok_(__FILE__, line)(hr == expected_hr, "Got hr %#x, expected %#x.\n", hr, expected_hr);
+ if (SUCCEEDED(hr))
+ IUnknown_Release(unk);
+}
+
static HRESULT WINAPI test_callback_QueryInterface(IMFPMediaPlayerCallback *iface, REFIID riid, void **obj)
{
if (IsEqualIID(riid, &IID_IMFPMediaPlayerCallback) ||
@@ -65,11 +80,32 @@ static const IMFPMediaPlayerCallbackVtbl test_callback_vtbl =
static void test_create_player(void)
{
IMFPMediaPlayerCallback callback = { &test_callback_vtbl };
+ IPropertyStore *propstore;
IMFPMediaPlayer *player;
+ IUnknown *unk, *unk2;
HRESULT hr;
hr = MFPCreateMediaPlayer(NULL, FALSE, 0, NULL, NULL, &player);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ check_interface(player, &IID_IMFPMediaPlayer, TRUE);
+ check_interface(player, &IID_IPropertyStore, TRUE);
+
+ hr = IMFPMediaPlayer_QueryInterface(player, &IID_IPropertyStore, (void **)&propstore);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ check_interface(propstore, &IID_IMFPMediaPlayer, TRUE);
+
+ hr = IPropertyStore_QueryInterface(propstore, &IID_IUnknown, (void **)&unk);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ hr = IMFPMediaPlayer_QueryInterface(player, &IID_IUnknown, (void **)&unk2);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ ok(unk == unk2, "Unexpected interface.\n");
+ IUnknown_Release(unk);
+ IUnknown_Release(unk2);
+
+ IPropertyStore_Release(propstore);
+
IMFPMediaPlayer_Release(player);
hr = MFPCreateMediaPlayer(NULL, FALSE, 0, &callback, NULL, &player);
More information about the wine-cvs
mailing list