Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- include/mfplay.idl | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/include/mfplay.idl b/include/mfplay.idl index f130ce12287..7d4345e69e7 100644 --- a/include/mfplay.idl +++ b/include/mfplay.idl @@ -22,13 +22,15 @@ import "evr.idl";
interface IMFNetCredential;
+typedef UINT32 MFP_CREATION_OPTIONS; + typedef [v1_enum] enum _MFP_CREATION_OPTIONS { MFP_OPTION_NONE = 0, MFP_OPTION_FREE_THREADED_CALLBACK = 0x1, MFP_OPTION_NO_MMCSS = 0x2, MFP_OPTION_NO_REMOTE_DESKTOP_OPTIMIZATION = 0x4, -} MFP_CREATION_OPTIONS; +} _MFP_CREATION_OPTIONS;
typedef [v1_enum] enum MFP_MEDIAPLAYER_STATE { @@ -180,6 +182,21 @@ typedef struct MFP_ACQUIRE_USER_CREDENTIAL_EVENT IMFNetCredential *pCredential; } MFP_ACQUIRE_USER_CREDENTIAL_EVENT;
+cpp_quote("#define __MFP_CAST_EVENT(hdr, tag) (((hdr)->eEventType == MFP_EVENT_TYPE_##tag) ? (MFP_##Tag##_EVENT *)(hdr) : NULL)") +cpp_quote("#define MFP_GET_PLAY_EVENT(hdr) __MFP_CAST_EVENT(hdr, PLAY)") +cpp_quote("#define MFP_GET_PAUSE_EVENT(hdr) __MFP_CAST_EVENT(hdr, PAUSE)") +cpp_quote("#define MFP_GET_STOP_EVENT(hdr) __MFP_CAST_EVENT(hdr, STOP)") +cpp_quote("#define MFP_GET_POSITION_SET_EVENT(hdr) __MFP_CAST_EVENT(hdr, POSITION_SET)") +cpp_quote("#define MFP_GET_RATE_SET_EVENT(hdr) __MFP_CAST_EVENT(hdr, RATE_SET)") +cpp_quote("#define MFP_GET_MEDIAITEM_CREATED_EVENT(hdr) __MFP_CAST_EVENT(hdr, MEDIAITEM_CREATED)") +cpp_quote("#define MFP_GET_MEDIAITEM_SET_EVENT(hdr) __MFP_CAST_EVENT(hdr, MEDIAITEM_SET)") +cpp_quote("#define MFP_GET_FRAME_STEP_EVENT(hdr) __MFP_CAST_EVENT(hdr, FRAME_STEP)") +cpp_quote("#define MFP_GET_MEDIAITEM_CLEARED_EVENT(hdr) __MFP_CAST_EVENT(hdr, MEDIAITEM_CLEARED)") +cpp_quote("#define MFP_GET_MF_EVENT(hdr) __MFP_CAST_EVENT(hdr, MF)") +cpp_quote("#define MFP_GET_ERROR_EVENT(hdr) __MFP_CAST_EVENT(hdr, ERROR)") +cpp_quote("#define MFP_GET_PLAYBACK_ENDED_EVENT(hdr) __MFP_CAST_EVENT(hdr, PLAYBACK_ENDED)") +cpp_quote("#define MFP_GET_ACQUIRE_USER_CREDENTIAL_EVENT(hdr) __MFP_CAST_EVENT(hdr, ACQUIRE_USER_CREDENTIAL)") + [ object, uuid(766c8ffb-5fdb-4fea-a28d-b912996f51bd),
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/player.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index d6ed6ef5c39..be51ef2d2e1 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -1605,6 +1605,21 @@ static void media_player_create_forward_event(struct media_player *player, HRESU LeaveCriticalSection(&player->cs); }
+static void media_player_create_playback_ended_event(struct media_player *player, HRESULT event_status, + struct media_event **event) +{ + EnterCriticalSection(&player->cs); + + if (SUCCEEDED(media_event_create(player, MFP_EVENT_TYPE_PLAYBACK_ENDED, event_status, player->item, event))) + { + if (player->item) + IMFPMediaItem_Release(player->item); + player->item = NULL; + } + + LeaveCriticalSection(&player->cs); +} + static HRESULT WINAPI media_player_session_events_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) { @@ -1616,6 +1631,7 @@ static HRESULT WINAPI media_player_session_events_callback_Invoke(IMFAsyncCallba HRESULT hr, event_status; IMFPMediaItem *item = NULL; IMFTopology *topology; + unsigned int status; PROPVARIANT value;
if (FAILED(hr = IMFMediaSession_EndGetEvent(player->session, result, &session_event))) @@ -1661,6 +1677,16 @@ static HRESULT WINAPI media_player_session_events_callback_Invoke(IMFAsyncCallba
break;
+ case MESessionTopologyStatus: + + if (SUCCEEDED(IMFMediaEvent_GetUINT32(session_event, &MF_EVENT_TOPOLOGY_STATUS, &status)) && + status == MF_TOPOSTATUS_ENDED) + { + media_player_create_playback_ended_event(player, event_status, &event); + } + + break; + case MEBufferingStarted: case MEBufferingStopped: case MEExtendedType:
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/player.c | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index be51ef2d2e1..51f3f67f5b1 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -34,6 +34,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
DEFINE_GUID(_MF_TOPO_MEDIA_ITEM, 0x6c1bb4df, 0x59ba, 0x4020, 0x85, 0x0c, 0x35, 0x79, 0xa2, 0x7a, 0xe2, 0x51); +DEFINE_GUID(_MF_CUSTOM_SINK, 0x7c1bb4df, 0x59ba, 0x4020, 0x85, 0x0c, 0x35, 0x79, 0xa2, 0x7a, 0xe2, 0x51);
static const WCHAR eventclassW[] = L"MediaPlayerEventCallbackClass";
@@ -550,9 +551,34 @@ static HRESULT WINAPI media_item_GetCharacteristics(IMFPMediaItem *iface, MFP_ME
static HRESULT WINAPI media_item_SetStreamSink(IMFPMediaItem *iface, DWORD index, IUnknown *sink) { - FIXME("%p, %u, %p.\n", iface, index, sink); + struct media_item *item = impl_from_IMFPMediaItem(iface); + IMFStreamDescriptor *sd; + IUnknown *sink_object; + BOOL selected; + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %u, %p.\n", iface, index, sink); + + if (FAILED(hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(item->pd, index, &selected, &sd))) + return hr; + + if (sink) + { + if (FAILED(hr = IUnknown_QueryInterface(sink, &IID_IMFStreamSink, (void **)&sink_object))) + hr = IUnknown_QueryInterface(sink, &IID_IMFActivate, (void **)&sink_object); + + if (sink_object) + { + hr = IMFStreamDescriptor_SetUnknown(sd, &_MF_CUSTOM_SINK, sink_object); + IUnknown_Release(sink_object); + } + } + else + IMFStreamDescriptor_DeleteItem(sd, &_MF_CUSTOM_SINK); + + IMFStreamDescriptor_Release(sd); + + return hr; }
static HRESULT WINAPI media_item_GetMetadata(IMFPMediaItem *iface, IPropertyStore **metadata)