mfplay: Add IPropertyStore support to media player object.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2021-04-05 09:10:59 +03:00 committed by Alexandre Julliard
parent 2efb464bab
commit 6a389d14a6
2 changed files with 149 additions and 9 deletions

View File

@ -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;
return E_NOINTERFACE;
}
WARN("Unsupported interface %s.\n", debugstr_guid(riid));
*obj = NULL;
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;
}

View File

@ -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);