Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/player.c | 18 ++++++++++++------ dlls/mfplay/tests/mfplay.c | 8 +++++++- 2 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index 246704c2799..479aca40890 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -69,6 +69,7 @@ struct media_player IMFSourceResolver *resolver; MFP_CREATION_OPTIONS options; HWND event_window; + HWND output_window; };
struct generic_event @@ -862,11 +863,15 @@ static HRESULT WINAPI media_player_GetAspectRatioMode(IMFPMediaPlayer *iface, return E_NOTIMPL; }
-static HRESULT WINAPI media_player_GetVideoWindow(IMFPMediaPlayer *iface, HWND *hwnd) +static HRESULT WINAPI media_player_GetVideoWindow(IMFPMediaPlayer *iface, HWND *window) { - FIXME("%p, %p.\n", iface, hwnd); + struct media_player *player = impl_from_IMFPMediaPlayer(iface);
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, window); + + *window = player->output_window; + + return S_OK; }
static HRESULT WINAPI media_player_UpdateVideo(IMFPMediaPlayer *iface) @@ -1166,12 +1171,12 @@ static const IMFAsyncCallbackVtbl media_player_events_callback_vtbl = };
HRESULT WINAPI MFPCreateMediaPlayer(const WCHAR *url, BOOL start_playback, MFP_CREATION_OPTIONS options, - IMFPMediaPlayerCallback *callback, HWND hwnd, IMFPMediaPlayer **player) + IMFPMediaPlayerCallback *callback, HWND window, 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); + TRACE("%s, %d, %#x, %p, %p, %p.\n", debugstr_w(url), start_playback, options, callback, window, player);
if (!(object = heap_alloc_zero(sizeof(*object)))) return E_OUTOFMEMORY; @@ -1184,9 +1189,10 @@ HRESULT WINAPI MFPCreateMediaPlayer(const WCHAR *url, BOOL start_playback, MFP_C object->events_callback.lpVtbl = &media_player_events_callback_vtbl; object->refcount = 1; object->callback = callback; - object->options = options; if (object->callback) IMFPMediaPlayerCallback_AddRef(object->callback); + object->options = options; + object->output_window = window; if (FAILED(hr = CreatePropertyStore(&object->propstore))) goto failed; if (FAILED(hr = MFCreateSourceResolver(&object->resolver))) diff --git a/dlls/mfplay/tests/mfplay.c b/dlls/mfplay/tests/mfplay.c index 64347265c40..6d82f630075 100644 --- a/dlls/mfplay/tests/mfplay.c +++ b/dlls/mfplay/tests/mfplay.c @@ -83,6 +83,7 @@ static void test_create_player(void) IPropertyStore *propstore; IMFPMediaPlayer *player; IUnknown *unk, *unk2; + HWND window; HRESULT hr;
hr = MFPCreateMediaPlayer(NULL, FALSE, 0, NULL, NULL, &player); @@ -108,8 +109,13 @@ static void test_create_player(void)
IMFPMediaPlayer_Release(player);
- hr = MFPCreateMediaPlayer(NULL, FALSE, 0, &callback, NULL, &player); + hr = MFPCreateMediaPlayer(NULL, FALSE, 0, &callback, (HWND)0x1, &player); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFPMediaPlayer_GetVideoWindow(player, &window); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(window == (HWND)0x1, "Unexpected window.\n"); + IMFPMediaPlayer_Release(player); }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/player.c | 51 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index 479aca40890..6fbbc0f4632 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -63,10 +63,12 @@ struct media_player IPropertyStore IPropertyStore_iface; IMFAsyncCallback resolver_callback; IMFAsyncCallback events_callback; + IMFAsyncCallback session_events_callback; LONG refcount; IMFPMediaPlayerCallback *callback; IPropertyStore *propstore; IMFSourceResolver *resolver; + IMFMediaSession *session; MFP_CREATION_OPTIONS options; HWND event_window; HWND output_window; @@ -121,6 +123,11 @@ static struct media_player *impl_from_events_IMFAsyncCallback(IMFAsyncCallback * return CONTAINING_RECORD(iface, struct media_player, events_callback); }
+static struct media_player *impl_from_session_events_IMFAsyncCallback(IMFAsyncCallback *iface) +{ + return CONTAINING_RECORD(iface, struct media_player, session_events_callback); +} + static struct media_item *impl_from_IMFPMediaItem(IMFPMediaItem *iface) { return CONTAINING_RECORD(iface, struct media_item, IMFPMediaItem_iface); @@ -618,6 +625,8 @@ static ULONG WINAPI media_player_Release(IMFPMediaPlayer *iface) IPropertyStore_Release(player->propstore); if (player->resolver) IMFSourceResolver_Release(player->resolver); + if (player->session) + IMFMediaSession_Release(player->session); DestroyWindow(player->event_window); heap_free(player);
@@ -1170,6 +1179,43 @@ static const IMFAsyncCallbackVtbl media_player_events_callback_vtbl = media_player_events_callback_Invoke, };
+static ULONG WINAPI media_player_session_events_callback_AddRef(IMFAsyncCallback *iface) +{ + struct media_player *player = impl_from_session_events_IMFAsyncCallback(iface); + return IMFPMediaPlayer_AddRef(&player->IMFPMediaPlayer_iface); +} + +static ULONG WINAPI media_player_session_events_callback_Release(IMFAsyncCallback *iface) +{ + struct media_player *player = impl_from_session_events_IMFAsyncCallback(iface); + return IMFPMediaPlayer_Release(&player->IMFPMediaPlayer_iface); +} + +static HRESULT WINAPI media_player_session_events_callback_Invoke(IMFAsyncCallback *iface, + IMFAsyncResult *result) +{ + struct media_player *player = impl_from_session_events_IMFAsyncCallback(iface); + IMFMediaEvent *event; + HRESULT hr; + + if (FAILED(hr = IMFMediaSession_EndGetEvent(player->session, result, &event))) + return S_OK; + + IMFMediaSession_BeginGetEvent(player->session, &player->session_events_callback, NULL); + IMFMediaEvent_Release(event); + + return S_OK; +} + +static const IMFAsyncCallbackVtbl media_player_session_events_callback_vtbl = +{ + media_player_callback_QueryInterface, + media_player_session_events_callback_AddRef, + media_player_session_events_callback_Release, + media_player_callback_GetParameters, + media_player_session_events_callback_Invoke, +}; + HRESULT WINAPI MFPCreateMediaPlayer(const WCHAR *url, BOOL start_playback, MFP_CREATION_OPTIONS options, IMFPMediaPlayerCallback *callback, HWND window, IMFPMediaPlayer **player) { @@ -1187,6 +1233,7 @@ HRESULT WINAPI MFPCreateMediaPlayer(const WCHAR *url, BOOL start_playback, MFP_C object->IPropertyStore_iface.lpVtbl = &media_player_propstore_vtbl; object->resolver_callback.lpVtbl = &media_player_resolver_callback_vtbl; object->events_callback.lpVtbl = &media_player_events_callback_vtbl; + object->session_events_callback.lpVtbl = &media_player_session_events_callback_vtbl; object->refcount = 1; object->callback = callback; if (object->callback) @@ -1197,6 +1244,10 @@ HRESULT WINAPI MFPCreateMediaPlayer(const WCHAR *url, BOOL start_playback, MFP_C goto failed; if (FAILED(hr = MFCreateSourceResolver(&object->resolver))) goto failed; + if (FAILED(hr = MFCreateMediaSession(NULL, &object->session))) + goto failed; + if (FAILED(hr = IMFMediaSession_BeginGetEvent(object->session, &object->session_events_callback, NULL))) + goto failed; if (!(object->options & MFP_OPTION_FREE_THREADED_CALLBACK)) { object->event_window = CreateWindowW(eventclassW, NULL, 0, 0, 0, 0, 0, HWND_MESSAGE,
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/player.c | 99 +++++++++++++++++++++++++++++++++++++------- 1 file changed, 85 insertions(+), 14 deletions(-)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index 6fbbc0f4632..16592f2b3b6 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -70,8 +70,10 @@ struct media_player IMFSourceResolver *resolver; IMFMediaSession *session; MFP_CREATION_OPTIONS options; + MFP_MEDIAPLAYER_STATE state; HWND event_window; HWND output_window; + CRITICAL_SECTION cs; };
struct generic_event @@ -215,8 +217,8 @@ static const IUnknownVtbl media_event_vtbl = media_event_Release, };
-static HRESULT media_event_create(MFP_EVENT_TYPE event_type, HRESULT hr, - IMFPMediaPlayer *player, struct media_event **event) +static HRESULT media_event_create(struct media_player *player, MFP_EVENT_TYPE event_type, + HRESULT hr, struct media_event **event) { struct media_event *object;
@@ -227,9 +229,9 @@ static HRESULT media_event_create(MFP_EVENT_TYPE event_type, HRESULT hr, object->refcount = 1; object->u.header.eEventType = event_type; object->u.header.hrEvent = hr; - object->u.header.pMediaPlayer = player; + object->u.header.pMediaPlayer = &player->IMFPMediaPlayer_iface; IMFPMediaPlayer_AddRef(object->u.header.pMediaPlayer); - /* FIXME: set player state field */ + object->u.header.eState = player->state; /* FIXME: set properties for some events? */
*event = object; @@ -254,6 +256,16 @@ static LRESULT WINAPI media_player_event_proc(HWND hwnd, UINT msg, WPARAM wparam return DefWindowProcW(hwnd, msg, wparam, lparam); }
+static void media_player_set_state(struct media_player *player, MFP_MEDIAPLAYER_STATE state) +{ + if (player->state != MFP_MEDIAPLAYER_STATE_SHUTDOWN) + { + if (state == MFP_MEDIAPLAYER_STATE_SHUTDOWN) + IMFMediaSession_Shutdown(player->session); + player->state = state; + } +} + static HRESULT WINAPI media_item_QueryInterface(IMFPMediaItem *iface, REFIID riid, void **obj) { TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); @@ -628,6 +640,7 @@ static ULONG WINAPI media_player_Release(IMFPMediaPlayer *iface) if (player->session) IMFMediaSession_Release(player->session); DestroyWindow(player->event_window); + DeleteCriticalSection(&player->cs); heap_free(player);
platform_shutdown(); @@ -708,9 +721,13 @@ static HRESULT WINAPI media_player_GetSupportedRates(IMFPMediaPlayer *iface, BOO
static HRESULT WINAPI media_player_GetState(IMFPMediaPlayer *iface, MFP_MEDIAPLAYER_STATE *state) { - FIXME("%p, %p.\n", iface, state); + struct media_player *player = impl_from_IMFPMediaPlayer(iface);
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, state); + + *state = player->state; + + return S_OK; }
static HRESULT WINAPI media_player_CreateMediaItemFromURL(IMFPMediaPlayer *iface, @@ -928,9 +945,15 @@ static HRESULT WINAPI media_player_RemoveAllEffects(IMFPMediaPlayer *iface)
static HRESULT WINAPI media_player_Shutdown(IMFPMediaPlayer *iface) { - FIXME("%p.\n", iface); + struct media_player *player = impl_from_IMFPMediaPlayer(iface);
- return E_NOTIMPL; + TRACE("%p.\n", iface); + + EnterCriticalSection(&player->cs); + media_player_set_state(player, MFP_MEDIAPLAYER_STATE_SHUTDOWN); + LeaveCriticalSection(&player->cs); + + return S_OK; }
static const IMFPMediaPlayerVtbl media_player_vtbl = @@ -1108,7 +1131,7 @@ 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(MFP_EVENT_TYPE_MEDIAITEM_CREATED, hr, &player->IMFPMediaPlayer_iface, &event))) + if (FAILED(media_event_create(player, MFP_EVENT_TYPE_MEDIAITEM_CREATED, hr, &event))) { WARN("Failed to create event object.\n"); IUnknown_Release(state); @@ -1195,14 +1218,61 @@ static HRESULT WINAPI media_player_session_events_callback_Invoke(IMFAsyncCallba IMFAsyncResult *result) { struct media_player *player = impl_from_session_events_IMFAsyncCallback(iface); - IMFMediaEvent *event; - HRESULT hr; - - if (FAILED(hr = IMFMediaSession_EndGetEvent(player->session, result, &event))) + MediaEventType session_event_type = MEUnknown; + struct media_event *event = NULL; + IMFMediaEvent *session_event; + MFP_MEDIAPLAYER_STATE state; + MFP_EVENT_TYPE event_type; + HRESULT hr, event_status; + + if (FAILED(hr = IMFMediaSession_EndGetEvent(player->session, result, &session_event))) return S_OK;
+ IMFMediaEvent_GetType(session_event, &session_event_type); + IMFMediaEvent_GetStatus(session_event, &event_status); + + 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; + state = MFP_MEDIAPLAYER_STATE_PAUSED; + } + + EnterCriticalSection(&player->cs); + media_player_set_state(player, state); + media_event_create(player, event_type, event_status, &event); + LeaveCriticalSection(&player->cs); + + /* FIXME: set pMediaItem */ + media_player_queue_event(player, event); + IUnknown_Release(&event->IUnknown_iface); + + break; + default: + ; + } + + if (event) + { + IUnknown_Release(&event->IUnknown_iface); + } + IMFMediaSession_BeginGetEvent(player->session, &player->session_events_callback, NULL); - IMFMediaEvent_Release(event); + IMFMediaEvent_Release(session_event);
return S_OK; } @@ -1240,6 +1310,7 @@ HRESULT WINAPI MFPCreateMediaPlayer(const WCHAR *url, BOOL start_playback, MFP_C IMFPMediaPlayerCallback_AddRef(object->callback); object->options = options; object->output_window = window; + InitializeCriticalSection(&object->cs); if (FAILED(hr = CreatePropertyStore(&object->propstore))) goto failed; if (FAILED(hr = MFCreateSourceResolver(&object->resolver)))
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/player.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index 16592f2b3b6..9ef926f00f6 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -651,23 +651,31 @@ static ULONG WINAPI media_player_Release(IMFPMediaPlayer *iface)
static HRESULT WINAPI media_player_Play(IMFPMediaPlayer *iface) { - FIXME("%p.\n", iface); + struct media_player *player = impl_from_IMFPMediaPlayer(iface); + PROPVARIANT pos;
- return E_NOTIMPL; + TRACE("%p.\n", iface); + + pos.vt = VT_EMPTY; + return IMFMediaSession_Start(player->session, &GUID_NULL, &pos); }
static HRESULT WINAPI media_player_Pause(IMFPMediaPlayer *iface) { - FIXME("%p.\n", iface); + struct media_player *player = impl_from_IMFPMediaPlayer(iface);
- return E_NOTIMPL; + TRACE("%p.\n", iface); + + return IMFMediaSession_Pause(player->session); }
static HRESULT WINAPI media_player_Stop(IMFPMediaPlayer *iface) { - FIXME("%p.\n", iface); + struct media_player *player = impl_from_IMFPMediaPlayer(iface);
- return E_NOTIMPL; + TRACE("%p.\n", iface); + + return IMFMediaSession_Stop(player->session); }
static HRESULT WINAPI media_player_FrameStep(IMFPMediaPlayer *iface)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/player.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index 9ef926f00f6..ddc83e9f441 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -407,9 +407,11 @@ static HRESULT WINAPI media_item_IsProtected(IMFPMediaItem *iface, BOOL *protect
static HRESULT WINAPI media_item_GetDuration(IMFPMediaItem *iface, REFGUID format, PROPVARIANT *value) { - FIXME("%p, %s, %p.\n", iface, debugstr_guid(format), value); + struct media_item *item = impl_from_IMFPMediaItem(iface);
- return E_NOTIMPL; + TRACE("%p, %s, %p.\n", iface, debugstr_guid(format), value); + + return IMFPresentationDescriptor_GetItem(item->pd, &MF_PD_DURATION, value); }
static HRESULT WINAPI media_item_GetNumberOfStreams(IMFPMediaItem *iface, DWORD *count)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/player.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index ddc83e9f441..3aa03103240 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -722,11 +722,23 @@ static HRESULT WINAPI media_player_GetRate(IMFPMediaPlayer *iface, float *rate) return E_NOTIMPL; }
-static HRESULT WINAPI media_player_GetSupportedRates(IMFPMediaPlayer *iface, BOOL forward, float *slowest_rate, float *fastest_rate) +static HRESULT WINAPI media_player_GetSupportedRates(IMFPMediaPlayer *iface, BOOL forward, + float *slowest_rate, float *fastest_rate) { - FIXME("%p, %d, %p, %p.\n", iface, forward, slowest_rate, fastest_rate); + struct media_player *player = impl_from_IMFPMediaPlayer(iface); + IMFRateSupport *rs; + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %d, %p, %p.\n", iface, forward, slowest_rate, fastest_rate); + + if (SUCCEEDED(hr = MFGetService((IUnknown *)player->session, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, (void **)&rs))) + { + if (SUCCEEDED(hr = IMFRateSupport_GetSlowestRate(rs, forward ? MFRATE_FORWARD : MFRATE_REVERSE, FALSE, slowest_rate))) + hr = IMFRateSupport_GetFastestRate(rs, forward ? MFRATE_FORWARD : MFRATE_REVERSE, FALSE, fastest_rate); + IMFRateSupport_Release(rs); + } + + return hr; }
static HRESULT WINAPI media_player_GetState(IMFPMediaPlayer *iface, MFP_MEDIAPLAYER_STATE *state)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/player.c | 7 +++++-- include/mfidl.idl | 1 + 2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index 3aa03103240..9f20d6c1a2a 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -503,9 +503,12 @@ static HRESULT WINAPI media_item_SetStreamSink(IMFPMediaItem *iface, DWORD index
static HRESULT WINAPI media_item_GetMetadata(IMFPMediaItem *iface, IPropertyStore **metadata) { - FIXME("%p, %p.\n", iface, metadata); + struct media_item *item = impl_from_IMFPMediaItem(iface);
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, metadata); + + return MFGetService((IUnknown *)item->source, &MF_PROPERTY_HANDLER_SERVICE, + &IID_IPropertyStore, (void **)&metadata); }
static const IMFPMediaItemVtbl media_item_vtbl = diff --git a/include/mfidl.idl b/include/mfidl.idl index 138b899ffdb..4e1a29d43d6 100644 --- a/include/mfidl.idl +++ b/include/mfidl.idl @@ -1385,6 +1385,7 @@ cpp_quote("EXTERN_GUID(MR_POLICY_VOLUME_SERVICE, 0x1abaa2ac, 0x9d3b, 0x47c6, 0xa cpp_quote("EXTERN_GUID(MR_CAPTURE_POLICY_VOLUME_SERVICE, 0x24030acd, 0x107a, 0x4265, 0x97, 0x5c, 0x41, 0x4e, 0x33, 0xe6, 0x5f, 0x2a);") cpp_quote("EXTERN_GUID(MR_STREAM_VOLUME_SERVICE, 0xf8b5fa2f, 0x32ef, 0x46f5, 0xb1, 0x72, 0x13, 0x21, 0x21, 0x2f, 0xb2, 0xc4);") cpp_quote("EXTERN_GUID(MR_AUDIO_POLICY_SERVICE, 0x911fd737, 0x6775, 0x4ab0, 0xa6, 0x14, 0x29, 0x78, 0x62, 0xfd, 0xac, 0x88);") +cpp_quote("EXTERN_GUID(MF_PROPERTY_HANDLER_SERVICE, 0xa3face02, 0x32b8, 0x41dd, 0x90, 0xe7, 0x5f, 0xef, 0x7c, 0x89, 0x91, 0xb5);")
cpp_quote("EXTERN_GUID(MF_SAMPLEGRABBERSINK_SAMPLE_TIME_OFFSET, 0x62e3d776, 0x8100, 0x4e03, 0xa6, 0xe8, 0xbd, 0x38, 0x57, 0xac, 0x9c, 0x47);") cpp_quote("EXTERN_GUID(MF_SAMPLEGRABBERSINK_IGNORE_CLOCK, 0x0efda2c0, 0x2b69, 0x4e2e, 0xab, 0x8d, 0x46, 0xdc, 0xbf, 0xf7, 0xd2, 0x5d);")
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/Makefile.in | 2 +- dlls/mfplay/player.c | 23 +++++++++++++++++++++-- 2 files changed, 22 insertions(+), 3 deletions(-)
diff --git a/dlls/mfplay/Makefile.in b/dlls/mfplay/Makefile.in index c353fa33cc1..8cd572bf638 100644 --- a/dlls/mfplay/Makefile.in +++ b/dlls/mfplay/Makefile.in @@ -1,6 +1,6 @@ MODULE = mfplay.dll IMPORTLIB = mfplay -IMPORTS = mfplat mf user32 uuid mfuuid +IMPORTS = mfplat mf ole32 user32 uuid mfuuid
EXTRADLLFLAGS = -mno-cygwin -Wb,--prefer-native
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index 9f20d6c1a2a..87a345e6968 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -24,6 +24,7 @@ #include "winbase.h" #include "mfapi.h" #include "mfplay.h" +#include "mferror.h"
#include "wine/debug.h" #include "wine/heap.h" @@ -55,6 +56,7 @@ struct media_item IMFMediaSource *source; IMFPresentationDescriptor *pd; DWORD_PTR user_data; + WCHAR *url; };
struct media_player @@ -308,6 +310,7 @@ static ULONG WINAPI media_item_Release(IMFPMediaItem *iface) IMFMediaSource_Release(item->source); if (item->pd) IMFPresentationDescriptor_Release(item->pd); + free(item->url); heap_free(item); }
@@ -329,9 +332,19 @@ static HRESULT WINAPI media_item_GetMediaPlayer(IMFPMediaItem *iface,
static HRESULT WINAPI media_item_GetURL(IMFPMediaItem *iface, LPWSTR *url) { - FIXME("%p, %p.\n", iface, url); + struct media_item *item = impl_from_IMFPMediaItem(iface);
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, url); + + if (!item->url) + return MF_E_NOT_FOUND; + + if (!(*url = CoTaskMemAlloc((wcslen(item->url) + 1) * sizeof(*item->url)))) + return E_OUTOFMEMORY; + + wcscpy(*url, item->url); + + return S_OK; }
static HRESULT WINAPI media_item_GetObject(IMFPMediaItem *iface, IUnknown **obj) @@ -769,6 +782,12 @@ static HRESULT WINAPI media_player_CreateMediaItemFromURL(IMFPMediaPlayer *iface if (FAILED(hr = create_media_item(iface, user_data, &item))) return hr;
+ if (url && !(item->url = wcsdup(url))) + { + IMFPMediaItem_Release(&item->IMFPMediaItem_iface); + return E_OUTOFMEMORY; + } + if (sync) { *ret = NULL;
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/player.c | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index 87a345e6968..0c72395ab1e 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -27,7 +27,6 @@ #include "mferror.h"
#include "wine/debug.h" -#include "wine/heap.h"
WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
@@ -206,7 +205,7 @@ static ULONG WINAPI media_event_Release(IUnknown *iface) break; }
- heap_free(event); + free(event); }
return refcount; @@ -224,7 +223,7 @@ static HRESULT media_event_create(struct media_player *player, MFP_EVENT_TYPE ev { struct media_event *object;
- if (!(object = heap_alloc_zero(sizeof(*object)))) + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY;
object->IUnknown_iface.lpVtbl = &media_event_vtbl; @@ -311,7 +310,7 @@ static ULONG WINAPI media_item_Release(IMFPMediaItem *iface) if (item->pd) IMFPresentationDescriptor_Release(item->pd); free(item->url); - heap_free(item); + free(item); }
return refcount; @@ -554,7 +553,7 @@ static HRESULT create_media_item(IMFPMediaPlayer *player, DWORD_PTR user_data, s { struct media_item *object;
- if (!(object = heap_alloc_zero(sizeof(*object)))) + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY;
object->IMFPMediaItem_iface.lpVtbl = &media_item_vtbl; @@ -659,7 +658,7 @@ static ULONG WINAPI media_player_Release(IMFPMediaPlayer *iface) IMFMediaSession_Release(player->session); DestroyWindow(player->event_window); DeleteCriticalSection(&player->cs); - heap_free(player); + free(player);
platform_shutdown(); } @@ -1338,7 +1337,7 @@ HRESULT WINAPI MFPCreateMediaPlayer(const WCHAR *url, BOOL start_playback, MFP_C
TRACE("%s, %d, %#x, %p, %p, %p.\n", debugstr_w(url), start_playback, options, callback, window, player);
- if (!(object = heap_alloc_zero(sizeof(*object)))) + if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY;
platform_startup();