Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/player.c | 138 +++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 132 insertions(+), 6 deletions(-)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index 0c72395ab1e..7360042ee54 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -19,6 +19,7 @@ #define COBJMACROS
#include <stdarg.h> +#include <assert.h>
#include "windef.h" #include "winbase.h" @@ -28,8 +29,12 @@
#include "wine/debug.h"
+#include "initguid.h" + WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
+DEFINE_GUID(_MF_TOPO_MEDIA_ITEM, 0x6c1bb4df, 0x59ba, 0x4020, 0x85, 0x0c, 0x35, 0x79, 0xa2, 0x7a, 0xe2, 0x51); + static const WCHAR eventclassW[] = L"MediaPlayerEventCallbackClass";
static LONG startup_refcount; @@ -549,6 +554,14 @@ static const IMFPMediaItemVtbl media_item_vtbl = media_item_GetMetadata, };
+static struct media_item *unsafe_impl_from_IMFPMediaItem(IMFPMediaItem *iface) +{ + if (!iface) + return NULL; + assert(iface->lpVtbl == (IMFPMediaItemVtbl *)&media_item_vtbl); + return CONTAINING_RECORD(iface, struct media_item, IMFPMediaItem_iface); +} + static HRESULT create_media_item(IMFPMediaPlayer *player, DWORD_PTR user_data, struct media_item **item) { struct media_item *object; @@ -822,11 +835,106 @@ static HRESULT WINAPI media_player_CreateMediaItemFromObject(IMFPMediaPlayer *if return E_NOTIMPL; }
-static HRESULT WINAPI media_player_SetMediaItem(IMFPMediaPlayer *iface, IMFPMediaItem *item) +static HRESULT media_item_get_stream_type(IMFStreamDescriptor *sd, GUID *major) { - FIXME("%p, %p.\n", iface, item); + IMFMediaTypeHandler *handler; + HRESULT hr;
- return E_NOTIMPL; + if (SUCCEEDED(hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &handler))) + { + hr = IMFMediaTypeHandler_GetMajorType(handler, major); + IMFMediaTypeHandler_Release(handler); + } + + return hr; +} + +static HRESULT media_item_create_topology(struct media_player *player, struct media_item *item, IMFTopology **out) +{ + IMFTopologyNode *src_node, *sink_node; + IMFActivate *sar_activate; + IMFStreamDescriptor *sd; + IMFTopology *topology; + unsigned int idx; + BOOL selected; + HRESULT hr; + GUID major; + + if (FAILED(hr = MFCreateTopology(&topology))) + return hr; + + /* FIXME: handle user sinks */ + + /* Use first stream if none selected. */ + if (player->output_window) + { + FIXME("Video streams are not handled.\n"); + } + + /* Set up audio branches for all selected streams. */ + + idx = 0; + while (SUCCEEDED(IMFPresentationDescriptor_GetStreamDescriptorByIndex(item->pd, idx++, &selected, &sd))) + { + if (selected && SUCCEEDED(media_item_get_stream_type(sd, &major)) && IsEqualGUID(&major, &MFMediaType_Audio)) + { + if (SUCCEEDED(hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &src_node))) + { + IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_SOURCE, (IUnknown *)item->source); + IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_PRESENTATION_DESCRIPTOR, (IUnknown *)item->pd); + IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_STREAM_DESCRIPTOR, (IUnknown *)sd); + + IMFTopology_AddNode(topology, src_node); + } + + if (SUCCEEDED(hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &sink_node))) + { + if (SUCCEEDED(MFCreateAudioRendererActivate(&sar_activate))) + { + IMFTopologyNode_SetObject(sink_node, (IUnknown *)sar_activate); + IMFActivate_Release(sar_activate); + } + + IMFTopology_AddNode(topology, sink_node); + } + + if (src_node && sink_node) + IMFTopologyNode_ConnectOutput(src_node, 0, sink_node, 0); + + if (src_node) + IMFTopologyNode_Release(src_node); + if (sink_node) + IMFTopologyNode_Release(sink_node); + } + + IMFStreamDescriptor_Release(sd); + } + + *out = topology; + + return S_OK; +} + +static HRESULT WINAPI media_player_SetMediaItem(IMFPMediaPlayer *iface, IMFPMediaItem *item_iface) +{ + struct media_player *player = impl_from_IMFPMediaPlayer(iface); + struct media_item *item = unsafe_impl_from_IMFPMediaItem(item_iface); + IMFTopology *topology; + HRESULT hr; + + TRACE("%p, %p.\n", iface, item_iface); + + if (item->player != iface) + return E_INVALIDARG; + + if (FAILED(hr = media_item_create_topology(player, item, &topology))) + return hr; + + IMFTopology_SetUnknown(topology, &_MF_TOPO_MEDIA_ITEM, (IUnknown *)item_iface); + hr = IMFMediaSession_SetTopology(player->session, MFSESSION_SETTOPOLOGY_IMMEDIATE, topology); + IMFTopology_Release(topology); + + return hr; }
static HRESULT WINAPI media_player_ClearMediaItem(IMFPMediaPlayer *iface) @@ -1267,6 +1375,8 @@ static HRESULT WINAPI media_player_session_events_callback_Invoke(IMFAsyncCallba MFP_MEDIAPLAYER_STATE state; MFP_EVENT_TYPE event_type; HRESULT hr, event_status; + IMFPMediaItem *item = NULL; + IMFTopology *topology;
if (FAILED(hr = IMFMediaSession_EndGetEvent(player->session, result, &session_event))) return S_OK; @@ -1274,6 +1384,12 @@ static HRESULT WINAPI media_player_session_events_callback_Invoke(IMFAsyncCallba IMFMediaEvent_GetType(session_event, &session_event_type); IMFMediaEvent_GetStatus(session_event, &event_status);
+ if (SUCCEEDED(IMFMediaSession_GetFullTopology(player->session, MFSESSION_GETFULLTOPOLOGY_CURRENT, 0, &topology))) + { + IMFTopology_GetUnknown(topology, &_MF_TOPO_MEDIA_ITEM, &IID_IMFPMediaItem, (void **)&item); + IMFTopology_Release(topology); + } + switch (session_event_type) { case MESessionStarted: @@ -1302,17 +1418,27 @@ static HRESULT WINAPI media_player_session_events_callback_Invoke(IMFAsyncCallba
/* FIXME: set pMediaItem */ media_player_queue_event(player, event); - IUnknown_Release(&event->IUnknown_iface); + + break; + + case MESessionTopologySet: + + media_event_create(player, MFP_EVENT_TYPE_MEDIAITEM_SET, event_status, &event); + event->u.generic.item = item; + if (event->u.generic.item) + IMFPMediaItem_AddRef(event->u.generic.item); + media_player_queue_event(player, event);
break; default: ; }
+ if (item) + IMFPMediaItem_Release(item); + if (event) - { IUnknown_Release(&event->IUnknown_iface); - }
IMFMediaSession_BeginGetEvent(player->session, &player->session_events_callback, NULL); IMFMediaEvent_Release(session_event);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/player.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index 7360042ee54..2f868ce3b61 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -1415,8 +1415,9 @@ static HRESULT WINAPI media_player_session_events_callback_Invoke(IMFAsyncCallba media_player_set_state(player, state); media_event_create(player, event_type, event_status, &event); LeaveCriticalSection(&player->cs); - - /* FIXME: set pMediaItem */ + event->u.generic.item = item; + if (event->u.generic.item) + IMFPMediaItem_AddRef(event->u.generic.item); media_player_queue_event(player, event);
break;
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=88632
Your paranoid android.
=== debiant2 (build log) ===
Task: Could not create the win32 wineprefix: Failed to disable the crash dialogs: Task: WineTest did not produce the win32 report
=== debiant2 (build log) ===
Task: Could not create the wow32 wineprefix: Failed to disable the crash dialogs: Task: WineTest did not produce the wow32 report
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/player.c | 181 ++++++++++++++++++++++++++++++++----------- 1 file changed, 137 insertions(+), 44 deletions(-)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index 2f868ce3b61..146c50fc755 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -75,6 +75,7 @@ struct media_player IPropertyStore *propstore; IMFSourceResolver *resolver; IMFMediaSession *session; + IMFPMediaItem *item; MFP_CREATION_OPTIONS options; MFP_MEDIAPLAYER_STATE state; HWND event_window; @@ -224,7 +225,7 @@ static const IUnknownVtbl media_event_vtbl = };
static HRESULT media_event_create(struct media_player *player, MFP_EVENT_TYPE event_type, - HRESULT hr, struct media_event **event) + HRESULT hr, IMFPMediaItem *item, struct media_event **event) { struct media_event *object;
@@ -238,6 +239,31 @@ static HRESULT media_event_create(struct media_player *player, MFP_EVENT_TYPE ev object->u.header.pMediaPlayer = &player->IMFPMediaPlayer_iface; IMFPMediaPlayer_AddRef(object->u.header.pMediaPlayer); object->u.header.eState = player->state; + switch (event_type) + { + case MFP_EVENT_TYPE_PLAY: + case MFP_EVENT_TYPE_PAUSE: + case MFP_EVENT_TYPE_STOP: + case MFP_EVENT_TYPE_POSITION_SET: + case MFP_EVENT_TYPE_RATE_SET: + case MFP_EVENT_TYPE_MEDIAITEM_CREATED: + case MFP_EVENT_TYPE_MEDIAITEM_SET: + case MFP_EVENT_TYPE_FRAME_STEP: + case MFP_EVENT_TYPE_MEDIAITEM_CLEARED: + case MFP_EVENT_TYPE_PLAYBACK_ENDED: + object->u.generic.item = item; + if (object->u.generic.item) + IMFPMediaItem_AddRef(object->u.generic.item); + break; + case MFP_EVENT_TYPE_MF: + object->u.event.pMediaItem = item; + if (object->u.event.pMediaItem) + IMFPMediaItem_AddRef(object->u.event.pMediaItem); + break; + default: + ; + } + /* FIXME: set properties for some events? */
*event = object; @@ -939,16 +965,34 @@ static HRESULT WINAPI media_player_SetMediaItem(IMFPMediaPlayer *iface, IMFPMedi
static HRESULT WINAPI media_player_ClearMediaItem(IMFPMediaPlayer *iface) { - FIXME("%p.\n", iface); + struct media_player *player = impl_from_IMFPMediaPlayer(iface);
- return E_NOTIMPL; + TRACE("%p.\n", iface); + + return IMFMediaSession_SetTopology(player->session, MFSESSION_SETTOPOLOGY_CLEAR_CURRENT, NULL); }
static HRESULT WINAPI media_player_GetMediaItem(IMFPMediaPlayer *iface, IMFPMediaItem **item) { - FIXME("%p, %p.\n", iface, item); + struct media_player *player = impl_from_IMFPMediaPlayer(iface); + HRESULT hr = S_OK;
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, item); + + if (!item) + return E_POINTER; + + EnterCriticalSection(&player->cs); + if (!player->item) + hr = MF_E_NOT_FOUND; + else + { + *item = player->item; + IMFPMediaItem_AddRef(player->item); + } + LeaveCriticalSection(&player->cs); + + return hr; }
static HRESULT WINAPI media_player_GetVolume(IMFPMediaPlayer *iface, float *volume) @@ -1102,6 +1146,11 @@ static HRESULT WINAPI media_player_Shutdown(IMFPMediaPlayer *iface)
EnterCriticalSection(&player->cs); media_player_set_state(player, MFP_MEDIAPLAYER_STATE_SHUTDOWN); + if (player->item) + { + IMFPMediaItem_Release(player->item); + player->item = NULL; + } LeaveCriticalSection(&player->cs);
return S_OK; @@ -1282,18 +1331,13 @@ static HRESULT WINAPI media_player_resolver_callback_Invoke(IMFAsyncCallback *if if (FAILED(hr)) WARN("Failed to set media source, hr %#x.\n", hr);
- if (FAILED(media_event_create(player, MFP_EVENT_TYPE_MEDIAITEM_CREATED, hr, &event))) + if (FAILED(media_event_create(player, MFP_EVENT_TYPE_MEDIAITEM_CREATED, hr, + &item->IMFPMediaItem_iface, &event))) { WARN("Failed to create event object.\n"); IUnknown_Release(state); return S_OK; } - - if (SUCCEEDED(hr)) - { - event->u.item_created.pMediaItem = &item->IMFPMediaItem_iface; - IMFPMediaItem_AddRef(event->u.item_created.pMediaItem); - } event->u.item_created.dwUserData = item->user_data;
media_player_queue_event(player, event); @@ -1365,6 +1409,63 @@ static ULONG WINAPI media_player_session_events_callback_Release(IMFAsyncCallbac return IMFPMediaPlayer_Release(&player->IMFPMediaPlayer_iface); }
+static void media_player_change_state(struct media_player *player, MFP_MEDIAPLAYER_STATE state, + HRESULT event_status, struct media_event **event) +{ + MFP_EVENT_TYPE event_type; + + EnterCriticalSection(&player->cs); + + if (state == MFP_MEDIAPLAYER_STATE_PLAYING) + event_type = MFP_EVENT_TYPE_PLAY; + else if (state == MFP_MEDIAPLAYER_STATE_PAUSED) + event_type = MFP_EVENT_TYPE_PAUSE; + else + event_type = MFP_EVENT_TYPE_STOP; + + media_player_set_state(player, state); + media_event_create(player, event_type, event_status, player->item, event); + + LeaveCriticalSection(&player->cs); +} + +static void media_player_set_item(struct media_player *player, IMFTopology *topology, HRESULT event_status, + struct media_event **event) +{ + IMFPMediaItem *item; + + if (FAILED(IMFTopology_GetUnknown(topology, &_MF_TOPO_MEDIA_ITEM, &IID_IMFPMediaItem, (void **)&item))) + return; + + EnterCriticalSection(&player->cs); + + if (player->item) + IMFPMediaItem_Release(player->item); + player->item = item; + IMFPMediaItem_AddRef(player->item); + + media_event_create(player, MFP_EVENT_TYPE_MEDIAITEM_SET, event_status, item, event); + + LeaveCriticalSection(&player->cs); + + IMFPMediaItem_Release(item); +} + +static void media_player_clear_item(struct media_player *player, HRESULT event_status, + struct media_event **event) +{ + IMFPMediaItem *item; + + EnterCriticalSection(&player->cs); + + item = player->item; + player->item = NULL; + + media_event_create(player, MFP_EVENT_TYPE_MEDIAITEM_SET, event_status, item, event); + + LeaveCriticalSection(&player->cs); +} + static HRESULT WINAPI media_player_session_events_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) { @@ -1373,10 +1474,10 @@ static HRESULT WINAPI media_player_session_events_callback_Invoke(IMFAsyncCallba struct media_event *event = NULL; IMFMediaEvent *session_event; MFP_MEDIAPLAYER_STATE state; - MFP_EVENT_TYPE event_type; HRESULT hr, event_status; IMFPMediaItem *item = NULL; IMFTopology *topology; + PROPVARIANT value;
if (FAILED(hr = IMFMediaSession_EndGetEvent(player->session, result, &session_event))) return S_OK; @@ -1384,51 +1485,40 @@ static HRESULT WINAPI media_player_session_events_callback_Invoke(IMFAsyncCallba IMFMediaEvent_GetType(session_event, &session_event_type); IMFMediaEvent_GetStatus(session_event, &event_status);
- if (SUCCEEDED(IMFMediaSession_GetFullTopology(player->session, MFSESSION_GETFULLTOPOLOGY_CURRENT, 0, &topology))) - { - IMFTopology_GetUnknown(topology, &_MF_TOPO_MEDIA_ITEM, &IID_IMFPMediaItem, (void **)&item); - IMFTopology_Release(topology); - } - switch (session_event_type) { case MESessionStarted: case MESessionStopped: case MESessionPaused: + if (session_event_type == MESessionStarted) - { - event_type = MFP_EVENT_TYPE_PLAY; state = MFP_MEDIAPLAYER_STATE_PLAYING; - } - else if (session_event_type == MESessionStopped) - { - event_type = MFP_EVENT_TYPE_STOP; - state = MFP_MEDIAPLAYER_STATE_STOPPED; - } - else - { - event_type = MFP_EVENT_TYPE_PAUSE; + else if (session_event_type == MESessionPaused) state = MFP_MEDIAPLAYER_STATE_PAUSED; - } + else + state = MFP_MEDIAPLAYER_STATE_STOPPED;
- EnterCriticalSection(&player->cs); - media_player_set_state(player, state); - media_event_create(player, event_type, event_status, &event); - LeaveCriticalSection(&player->cs); - event->u.generic.item = item; - if (event->u.generic.item) - IMFPMediaItem_AddRef(event->u.generic.item); - media_player_queue_event(player, event); + media_player_change_state(player, state, event_status, &event);
break;
case MESessionTopologySet:
- media_event_create(player, MFP_EVENT_TYPE_MEDIAITEM_SET, event_status, &event); - event->u.generic.item = item; - if (event->u.generic.item) - IMFPMediaItem_AddRef(event->u.generic.item); - media_player_queue_event(player, event); + value.vt = VT_EMPTY; + if (SUCCEEDED(IMFMediaEvent_GetValue(session_event, &value))) + { + if (value.vt == VT_EMPTY) + { + media_player_clear_item(player, event_status, &event); + } + else if (value.vt == VT_UNKNOWN && value.punkVal && + SUCCEEDED(IUnknown_QueryInterface(value.punkVal, &IID_IMFTopology, (void **)&topology))) + { + media_player_set_item(player, topology, event_status, &event); + IMFTopology_Release(topology); + } + PropVariantClear(&value); + }
break; default: @@ -1439,7 +1529,10 @@ static HRESULT WINAPI media_player_session_events_callback_Invoke(IMFAsyncCallba IMFPMediaItem_Release(item);
if (event) + { + media_player_queue_event(player, event); IUnknown_Release(&event->IUnknown_iface); + }
IMFMediaSession_BeginGetEvent(player->session, &player->session_events_callback, NULL); IMFMediaEvent_Release(session_event);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=88633
Your paranoid android.
=== debiant2 (build log) ===
Task: Could not create the win32 wineprefix: Failed to disable the crash dialogs: Task: WineTest did not produce the win32 report
=== debiant2 (build log) ===
Task: Could not create the wow32 wineprefix: Failed to disable the crash dialogs: Task: WineTest did not produce the wow32 report
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/player.c | 27 ++++++++++++++---- dlls/mfplay/tests/mfplay.c | 57 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 78 insertions(+), 6 deletions(-)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index 146c50fc755..a45c5ac9ffa 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -806,18 +806,17 @@ static HRESULT WINAPI media_player_GetState(IMFPMediaPlayer *iface, MFP_MEDIAPLA return S_OK; }
-static HRESULT WINAPI media_player_CreateMediaItemFromURL(IMFPMediaPlayer *iface, +static HRESULT media_player_create_item_from_url(struct media_player *player, const WCHAR *url, BOOL sync, DWORD_PTR user_data, IMFPMediaItem **ret) { - struct media_player *player = impl_from_IMFPMediaPlayer(iface); struct media_item *item; MF_OBJECT_TYPE obj_type; IUnknown *object; HRESULT hr;
- TRACE("%p, %s, %d, %lx, %p.\n", iface, debugstr_w(url), sync, user_data, ret); + *ret = NULL;
- if (FAILED(hr = create_media_item(iface, user_data, &item))) + if (FAILED(hr = create_media_item(&player->IMFPMediaPlayer_iface, user_data, &item))) return hr;
if (url && !(item->url = wcsdup(url))) @@ -828,8 +827,6 @@ static HRESULT WINAPI media_player_CreateMediaItemFromURL(IMFPMediaPlayer *iface
if (sync) { - *ret = NULL; - if (SUCCEEDED(hr = IMFSourceResolver_CreateObjectFromURL(player->resolver, url, MF_RESOLUTION_MEDIASOURCE, player->propstore, &obj_type, &object))) { @@ -853,6 +850,24 @@ static HRESULT WINAPI media_player_CreateMediaItemFromURL(IMFPMediaPlayer *iface return hr; }
+static HRESULT WINAPI media_player_CreateMediaItemFromURL(IMFPMediaPlayer *iface, + const WCHAR *url, BOOL sync, DWORD_PTR user_data, IMFPMediaItem **ret) +{ + struct media_player *player = impl_from_IMFPMediaPlayer(iface); + HRESULT hr; + + TRACE("%p, %s, %d, %lx, %p.\n", iface, debugstr_w(url), sync, user_data, ret); + + EnterCriticalSection(&player->cs); + if (player->state == MFP_MEDIAPLAYER_STATE_SHUTDOWN) + hr = MF_E_SHUTDOWN; + else + hr = media_player_create_item_from_url(player, url, sync, user_data, ret); + LeaveCriticalSection(&player->cs); + + return hr; +} + static HRESULT WINAPI media_player_CreateMediaItemFromObject(IMFPMediaPlayer *iface, IUnknown *object, BOOL sync, DWORD_PTR user_data, IMFPMediaItem **item) { diff --git a/dlls/mfplay/tests/mfplay.c b/dlls/mfplay/tests/mfplay.c index 6d82f630075..c9a07ca9d81 100644 --- a/dlls/mfplay/tests/mfplay.c +++ b/dlls/mfplay/tests/mfplay.c @@ -23,6 +23,7 @@ #include "windef.h" #include "winbase.h" #include "mfplay.h" +#include "mferror.h"
#include "wine/test.h"
@@ -119,7 +120,63 @@ static void test_create_player(void) IMFPMediaPlayer_Release(player); }
+static void test_shutdown(void) +{ + IMFPMediaPlayer *player; + float slowest, fastest; + HRESULT hr; + MFP_MEDIAPLAYER_STATE state; + IMFPMediaItem *item; + HWND window; + + hr = MFPCreateMediaPlayer(NULL, FALSE, 0, NULL, NULL, &player); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFPMediaPlayer_GetState(player, &state); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(state == MFP_MEDIAPLAYER_STATE_EMPTY, "Unexpected state %d.\n", state); + + hr = IMFPMediaPlayer_Shutdown(player); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + /* Check methods in shutdown state. */ + hr = IMFPMediaPlayer_Play(player); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + + hr = IMFPMediaPlayer_Pause(player); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + + hr = IMFPMediaPlayer_Stop(player); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + + hr = IMFPMediaPlayer_GetSupportedRates(player, TRUE, &slowest, &fastest); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + + hr = IMFPMediaPlayer_GetState(player, &state); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(state == MFP_MEDIAPLAYER_STATE_SHUTDOWN, "Unexpected state %d.\n", state); + + hr = IMFPMediaPlayer_CreateMediaItemFromURL(player, L"url", TRUE, 0, &item); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + + hr = IMFPMediaPlayer_ClearMediaItem(player); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + + hr = IMFPMediaPlayer_GetMediaItem(player, &item); +todo_wine + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + + hr = IMFPMediaPlayer_GetVideoWindow(player, &window); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFPMediaPlayer_Shutdown(player); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + IMFPMediaPlayer_Release(player); +} + START_TEST(mfplay) { test_create_player(); + test_shutdown(); }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=88634
Your paranoid android.
=== debiant2 (build log) ===
Task: Could not create the win32 wineprefix: Failed to disable the crash dialogs: Task: WineTest did not produce the win32 report
=== debiant2 (build log) ===
Task: Could not create the wow32 wineprefix: Failed to disable the crash dialogs: Task: WineTest did not produce the wow32 report
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/player.c | 4 +++- dlls/mfplay/tests/mfplay.c | 1 - 2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index a45c5ac9ffa..e061e21acb8 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -998,7 +998,9 @@ static HRESULT WINAPI media_player_GetMediaItem(IMFPMediaPlayer *iface, IMFPMedi return E_POINTER;
EnterCriticalSection(&player->cs); - if (!player->item) + if (player->state == MFP_MEDIAPLAYER_STATE_SHUTDOWN) + hr = MF_E_SHUTDOWN; + else if (!player->item) hr = MF_E_NOT_FOUND; else { diff --git a/dlls/mfplay/tests/mfplay.c b/dlls/mfplay/tests/mfplay.c index c9a07ca9d81..64a48cceaca 100644 --- a/dlls/mfplay/tests/mfplay.c +++ b/dlls/mfplay/tests/mfplay.c @@ -163,7 +163,6 @@ static void test_shutdown(void) ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
hr = IMFPMediaPlayer_GetMediaItem(player, &item); -todo_wine ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
hr = IMFPMediaPlayer_GetVideoWindow(player, &window);
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=88635
Your paranoid android.
=== debiant2 (build log) ===
Task: Could not create the win32 wineprefix: Failed to disable the crash dialogs: Task: WineTest did not produce the win32 report
=== debiant2 (build log) ===
Task: Could not create the wow32 wineprefix: Failed to disable the crash dialogs: Task: WineTest did not produce the wow32 report
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/player.c | 5 +++++ 1 file changed, 5 insertions(+)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index e061e21acb8..a95e1d3ca36 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -835,7 +835,12 @@ static HRESULT media_player_create_item_from_url(struct media_player *player, }
if (SUCCEEDED(hr)) + { *ret = &item->IMFPMediaItem_iface; + IMFPMediaItem_AddRef(*ret); + } + + IMFPMediaItem_Release(&item->IMFPMediaItem_iface);
return hr; }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=88636
Your paranoid android.
=== debiant2 (build log) ===
Task: Could not create the win32 wineprefix: Failed to disable the crash dialogs: Task: WineTest did not produce the win32 report
=== debiant2 (build log) ===
Task: Could not create the wow32 wineprefix: Failed to disable the crash dialogs: Task: WineTest did not produce the wow32 report
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/player.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index a95e1d3ca36..b098d880461 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -1488,6 +1488,21 @@ static void media_player_clear_item(struct media_player *player, HRESULT event_s LeaveCriticalSection(&player->cs); }
+static void media_player_create_forward_event(struct media_player *player, HRESULT event_status, IMFMediaEvent *session_event, + struct media_event **event) +{ + EnterCriticalSection(&player->cs); + + if (SUCCEEDED(media_event_create(player, MFP_EVENT_TYPE_MF, event_status, player->item, event))) + { + IMFMediaEvent_GetType(session_event, &(*event)->u.event.MFEventType); + (*event)->u.event.pMFMediaEvent = session_event; + IMFMediaEvent_AddRef((*event)->u.event.pMFMediaEvent); + } + + LeaveCriticalSection(&player->cs); +} + static HRESULT WINAPI media_player_session_events_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) { @@ -1543,6 +1558,19 @@ static HRESULT WINAPI media_player_session_events_callback_Invoke(IMFAsyncCallba }
break; + + case MEBufferingStarted: + case MEBufferingStopped: + case MEExtendedType: + case MEReconnectStart: + case MEReconnectEnd: + case MERendererEvent: + case MEStreamSinkFormatChanged: + + media_player_create_forward_event(player, event_status, session_event, &event); + + break; + default: ; }
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=88637
Your paranoid android.
=== debiant2 (build log) ===
Task: Could not create the win32 wineprefix: Failed to disable the crash dialogs: Task: WineTest did not produce the win32 report
=== debiant2 (build log) ===
Task: Could not create the wow32 wineprefix: Failed to disable the crash dialogs: Task: WineTest did not produce the wow32 report
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=88631
Your paranoid android.
=== debiant2 (build log) ===
Task: Could not create the win32 wineprefix: Failed to disable the crash dialogs: Task: WineTest did not produce the win32 report
=== debiant2 (build log) ===
Task: Could not create the wow32 wineprefix: Failed to disable the crash dialogs: Task: WineTest did not produce the wow32 report