mfplay: Add support for same-thread event callback.

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-06 10:25:32 +03:00 committed by Alexandre Julliard
parent ef908ef248
commit 826be590c0
2 changed files with 59 additions and 2 deletions

View File

@ -1,6 +1,6 @@
MODULE = mfplay.dll
IMPORTLIB = mfplay
IMPORTS = mfplat mf uuid mfuuid
IMPORTS = mfplat mf user32 uuid mfuuid
EXTRADLLFLAGS = -mno-cygwin -Wb,--prefer-native

View File

@ -30,7 +30,10 @@
WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
static const WCHAR eventclassW[] = L"MediaPlayerEventCallbackClass";
static LONG startup_refcount;
static HINSTANCE mfplay_instance;
static void platform_startup(void)
{
@ -65,6 +68,7 @@ struct media_player
IPropertyStore *propstore;
IMFSourceResolver *resolver;
MFP_CREATION_OPTIONS options;
HWND event_window;
};
struct generic_event
@ -225,6 +229,23 @@ static HRESULT media_event_create(MFP_EVENT_TYPE event_type, HRESULT hr,
return S_OK;
}
static LRESULT WINAPI media_player_event_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
struct media_event *event = (void *)lparam;
struct media_player *player;
if (msg == WM_USER)
{
player = impl_from_IMFPMediaPlayer(event->u.header.pMediaPlayer);
if (player->callback)
IMFPMediaPlayerCallback_OnMediaPlayerEvent(player->callback, &event->u.header);
IUnknown_Release(&event->IUnknown_iface);
return 0;
}
return DefWindowProcW(hwnd, msg, wparam, lparam);
}
static HRESULT WINAPI media_item_QueryInterface(IMFPMediaItem *iface, REFIID riid, void **obj)
{
TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
@ -539,7 +560,8 @@ static void media_player_queue_event(struct media_player *player, struct media_e
}
else
{
/* FIXME: same-thread callback notification */
IUnknown_AddRef(&event->IUnknown_iface);
PostMessageW(player->event_window, WM_USER, 0, (LPARAM)event);
}
}
@ -595,6 +617,7 @@ static ULONG WINAPI media_player_Release(IMFPMediaPlayer *iface)
IPropertyStore_Release(player->propstore);
if (player->resolver)
IMFSourceResolver_Release(player->resolver);
DestroyWindow(player->event_window);
heap_free(player);
platform_shutdown();
@ -1168,6 +1191,11 @@ HRESULT WINAPI MFPCreateMediaPlayer(const WCHAR *url, BOOL start_playback, MFP_C
goto failed;
if (FAILED(hr = MFCreateSourceResolver(&object->resolver)))
goto failed;
if (!(object->options & MFP_OPTION_FREE_THREADED_CALLBACK))
{
object->event_window = CreateWindowW(eventclassW, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE,
0, mfplay_instance, NULL);
}
*player = &object->IMFPMediaPlayer_iface;
@ -1179,3 +1207,32 @@ failed:
return hr;
}
static void media_player_register_window_class(void)
{
WNDCLASSW cls = { 0 };
cls.lpfnWndProc = media_player_event_proc;
cls.hInstance = mfplay_instance;
cls.lpszClassName = eventclassW;
RegisterClassW(&cls);
}
BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, void *reserved)
{
switch (reason)
{
case DLL_PROCESS_ATTACH:
mfplay_instance = instance;
DisableThreadLibraryCalls(instance);
media_player_register_window_class();
break;
case DLL_PROCESS_DETACH:
if (reserved) break;
UnregisterClassW(eventclassW, instance);
break;
}
return TRUE;
}