2 * Copyright 2019 Nikolay Sivov for CodeWeavers
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
28 #include "wine/debug.h"
29 #include "wine/heap.h"
31 WINE_DEFAULT_DEBUG_CHANNEL(mfplat
);
33 static const WCHAR eventclassW
[] = L
"MediaPlayerEventCallbackClass";
35 static LONG startup_refcount
;
36 static HINSTANCE mfplay_instance
;
38 static void platform_startup(void)
40 if (InterlockedIncrement(&startup_refcount
) == 1)
41 MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
44 static void platform_shutdown(void)
46 if (InterlockedDecrement(&startup_refcount
) == 0)
52 IMFPMediaItem IMFPMediaItem_iface
;
54 IMFPMediaPlayer
*player
;
55 IMFMediaSource
*source
;
56 IMFPresentationDescriptor
*pd
;
62 IMFPMediaPlayer IMFPMediaPlayer_iface
;
63 IPropertyStore IPropertyStore_iface
;
64 IMFAsyncCallback resolver_callback
;
65 IMFAsyncCallback events_callback
;
67 IMFPMediaPlayerCallback
*callback
;
68 IPropertyStore
*propstore
;
69 IMFSourceResolver
*resolver
;
70 MFP_CREATION_OPTIONS options
;
76 MFP_EVENT_HEADER header
;
82 IUnknown IUnknown_iface
;
86 MFP_EVENT_HEADER header
;
87 struct generic_event generic
;
89 MFP_PAUSE_EVENT pause
;
91 MFP_POSITION_SET_EVENT position_set
;
92 MFP_RATE_SET_EVENT rate_set
;
93 MFP_MEDIAITEM_CREATED_EVENT item_created
;
94 MFP_MEDIAITEM_SET_EVENT item_set
;
95 MFP_MEDIAITEM_CLEARED_EVENT item_cleared
;
97 MFP_ERROR_EVENT error
;
98 MFP_PLAYBACK_ENDED_EVENT ended
;
99 MFP_ACQUIRE_USER_CREDENTIAL_EVENT acquire_creds
;
103 static struct media_player
*impl_from_IMFPMediaPlayer(IMFPMediaPlayer
*iface
)
105 return CONTAINING_RECORD(iface
, struct media_player
, IMFPMediaPlayer_iface
);
108 static struct media_player
*impl_from_IPropertyStore(IPropertyStore
*iface
)
110 return CONTAINING_RECORD(iface
, struct media_player
, IPropertyStore_iface
);
113 static struct media_player
*impl_from_resolver_IMFAsyncCallback(IMFAsyncCallback
*iface
)
115 return CONTAINING_RECORD(iface
, struct media_player
, resolver_callback
);
118 static struct media_player
*impl_from_events_IMFAsyncCallback(IMFAsyncCallback
*iface
)
120 return CONTAINING_RECORD(iface
, struct media_player
, events_callback
);
123 static struct media_item
*impl_from_IMFPMediaItem(IMFPMediaItem
*iface
)
125 return CONTAINING_RECORD(iface
, struct media_item
, IMFPMediaItem_iface
);
128 static struct media_event
*impl_event_from_IUnknown(IUnknown
*iface
)
130 return CONTAINING_RECORD(iface
, struct media_event
, IUnknown_iface
);
133 static HRESULT WINAPI
media_event_QueryInterface(IUnknown
*iface
, REFIID riid
, void **obj
)
135 if (IsEqualIID(riid
, &IID_IUnknown
))
138 IUnknown_AddRef(iface
);
143 return E_NOINTERFACE
;
146 static ULONG WINAPI
media_event_AddRef(IUnknown
*iface
)
148 struct media_event
*event
= impl_event_from_IUnknown(iface
);
149 ULONG refcount
= InterlockedIncrement(&event
->refcount
);
151 TRACE("%p, refcount %u.\n", iface
, refcount
);
156 static ULONG WINAPI
media_event_Release(IUnknown
*iface
)
158 struct media_event
*event
= impl_event_from_IUnknown(iface
);
159 ULONG refcount
= InterlockedDecrement(&event
->refcount
);
161 TRACE("%p, refcount %u.\n", iface
, refcount
);
165 if (event
->u
.header
.pMediaPlayer
)
166 IMFPMediaPlayer_Release(event
->u
.header
.pMediaPlayer
);
167 if (event
->u
.header
.pPropertyStore
)
168 IPropertyStore_Release(event
->u
.header
.pPropertyStore
);
170 switch (event
->u
.header
.eEventType
)
172 /* Most types share same layout. */
173 case MFP_EVENT_TYPE_PLAY
:
174 case MFP_EVENT_TYPE_PAUSE
:
175 case MFP_EVENT_TYPE_STOP
:
176 case MFP_EVENT_TYPE_POSITION_SET
:
177 case MFP_EVENT_TYPE_RATE_SET
:
178 case MFP_EVENT_TYPE_MEDIAITEM_CREATED
:
179 case MFP_EVENT_TYPE_MEDIAITEM_SET
:
180 case MFP_EVENT_TYPE_FRAME_STEP
:
181 case MFP_EVENT_TYPE_MEDIAITEM_CLEARED
:
182 case MFP_EVENT_TYPE_PLAYBACK_ENDED
:
183 if (event
->u
.generic
.item
)
184 IMFPMediaItem_Release(event
->u
.generic
.item
);
186 case MFP_EVENT_TYPE_MF
:
187 if (event
->u
.event
.pMFMediaEvent
)
188 IMFMediaEvent_Release(event
->u
.event
.pMFMediaEvent
);
189 if (event
->u
.event
.pMediaItem
)
190 IMFPMediaItem_Release(event
->u
.event
.pMediaItem
);
193 FIXME("Unsupported event %u.\n", event
->u
.header
.eEventType
);
203 static const IUnknownVtbl media_event_vtbl
=
205 media_event_QueryInterface
,
210 static HRESULT
media_event_create(MFP_EVENT_TYPE event_type
, HRESULT hr
,
211 IMFPMediaPlayer
*player
, struct media_event
**event
)
213 struct media_event
*object
;
215 if (!(object
= heap_alloc_zero(sizeof(*object
))))
216 return E_OUTOFMEMORY
;
218 object
->IUnknown_iface
.lpVtbl
= &media_event_vtbl
;
219 object
->refcount
= 1;
220 object
->u
.header
.eEventType
= event_type
;
221 object
->u
.header
.hrEvent
= hr
;
222 object
->u
.header
.pMediaPlayer
= player
;
223 IMFPMediaPlayer_AddRef(object
->u
.header
.pMediaPlayer
);
224 /* FIXME: set player state field */
225 /* FIXME: set properties for some events? */
232 static LRESULT WINAPI
media_player_event_proc(HWND hwnd
, UINT msg
, WPARAM wparam
, LPARAM lparam
)
234 struct media_event
*event
= (void *)lparam
;
235 struct media_player
*player
;
239 player
= impl_from_IMFPMediaPlayer(event
->u
.header
.pMediaPlayer
);
240 if (player
->callback
)
241 IMFPMediaPlayerCallback_OnMediaPlayerEvent(player
->callback
, &event
->u
.header
);
242 IUnknown_Release(&event
->IUnknown_iface
);
246 return DefWindowProcW(hwnd
, msg
, wparam
, lparam
);
249 static HRESULT WINAPI
media_item_QueryInterface(IMFPMediaItem
*iface
, REFIID riid
, void **obj
)
251 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
253 if (IsEqualIID(riid
, &IID_IMFPMediaItem
) ||
254 IsEqualIID(riid
, &IID_IUnknown
))
257 IMFPMediaItem_AddRef(iface
);
261 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
263 return E_NOINTERFACE
;
266 static ULONG WINAPI
media_item_AddRef(IMFPMediaItem
*iface
)
268 struct media_item
*item
= impl_from_IMFPMediaItem(iface
);
269 ULONG refcount
= InterlockedIncrement(&item
->refcount
);
271 TRACE("%p, refcount %u.\n", iface
, refcount
);
276 static ULONG WINAPI
media_item_Release(IMFPMediaItem
*iface
)
278 struct media_item
*item
= impl_from_IMFPMediaItem(iface
);
279 ULONG refcount
= InterlockedDecrement(&item
->refcount
);
281 TRACE("%p, refcount %u.\n", iface
, refcount
);
286 IMFPMediaPlayer_Release(item
->player
);
288 IMFMediaSource_Release(item
->source
);
290 IMFPresentationDescriptor_Release(item
->pd
);
297 static HRESULT WINAPI
media_item_GetMediaPlayer(IMFPMediaItem
*iface
,
298 IMFPMediaPlayer
**player
)
300 struct media_item
*item
= impl_from_IMFPMediaItem(iface
);
302 TRACE("%p, %p.\n", iface
, player
);
304 *player
= item
->player
;
305 IMFPMediaPlayer_AddRef(*player
);
310 static HRESULT WINAPI
media_item_GetURL(IMFPMediaItem
*iface
, LPWSTR
*url
)
312 FIXME("%p, %p.\n", iface
, url
);
317 static HRESULT WINAPI
media_item_GetObject(IMFPMediaItem
*iface
, IUnknown
**obj
)
319 FIXME("%p, %p.\n", iface
, obj
);
324 static HRESULT WINAPI
media_item_GetUserData(IMFPMediaItem
*iface
, DWORD_PTR
*user_data
)
326 struct media_item
*item
= impl_from_IMFPMediaItem(iface
);
328 TRACE("%p, %p.\n", iface
, user_data
);
330 *user_data
= item
->user_data
;
335 static HRESULT WINAPI
media_item_SetUserData(IMFPMediaItem
*iface
, DWORD_PTR user_data
)
337 struct media_item
*item
= impl_from_IMFPMediaItem(iface
);
339 TRACE("%p, %lx.\n", iface
, user_data
);
341 item
->user_data
= user_data
;
346 static HRESULT WINAPI
media_item_GetStartStopPosition(IMFPMediaItem
*iface
, GUID
*start_format
,
347 PROPVARIANT
*start_position
, GUID
*stop_format
, PROPVARIANT
*stop_position
)
349 FIXME("%p, %p, %p, %p, %p.\n", iface
, start_format
, start_position
, stop_format
, stop_position
);
354 static HRESULT WINAPI
media_item_SetStartStopPosition(IMFPMediaItem
*iface
, const GUID
*start_format
,
355 const PROPVARIANT
*start_position
, const GUID
*stop_format
, const PROPVARIANT
*stop_position
)
357 FIXME("%p, %s, %p, %s, %p.\n", iface
, debugstr_guid(start_format
), start_position
,
358 debugstr_guid(stop_format
), stop_position
);
363 static HRESULT WINAPI
media_item_HasVideo(IMFPMediaItem
*iface
, BOOL
*has_video
, BOOL
*selected
)
365 FIXME("%p, %p, %p.\n", iface
, has_video
, selected
);
370 static HRESULT WINAPI
media_item_HasAudio(IMFPMediaItem
*iface
, BOOL
*has_audio
, BOOL
*selected
)
372 FIXME("%p, %p, %p.\n", iface
, has_audio
, selected
);
377 static HRESULT WINAPI
media_item_IsProtected(IMFPMediaItem
*iface
, BOOL
*protected)
379 struct media_item
*item
= impl_from_IMFPMediaItem(iface
);
381 TRACE("%p, %p.\n", iface
, protected);
383 *protected = MFRequireProtectedEnvironment(item
->pd
) == S_OK
;
388 static HRESULT WINAPI
media_item_GetDuration(IMFPMediaItem
*iface
, REFGUID format
, PROPVARIANT
*value
)
390 FIXME("%p, %s, %p.\n", iface
, debugstr_guid(format
), value
);
395 static HRESULT WINAPI
media_item_GetNumberOfStreams(IMFPMediaItem
*iface
, DWORD
*count
)
397 struct media_item
*item
= impl_from_IMFPMediaItem(iface
);
399 TRACE("%p, %p.\n", iface
, count
);
401 return IMFPresentationDescriptor_GetStreamDescriptorCount(item
->pd
, count
);
404 static HRESULT WINAPI
media_item_GetStreamSelection(IMFPMediaItem
*iface
, DWORD index
, BOOL
*selected
)
406 struct media_item
*item
= impl_from_IMFPMediaItem(iface
);
407 IMFStreamDescriptor
*sd
;
410 TRACE("%p, %u, %p.\n", iface
, index
, selected
);
412 if (SUCCEEDED(hr
= IMFPresentationDescriptor_GetStreamDescriptorByIndex(item
->pd
, index
, selected
, &sd
)))
413 IMFStreamDescriptor_Release(sd
);
418 static HRESULT WINAPI
media_item_SetStreamSelection(IMFPMediaItem
*iface
, DWORD index
, BOOL select
)
420 struct media_item
*item
= impl_from_IMFPMediaItem(iface
);
422 TRACE("%p, %u, %d.\n", iface
, index
, select
);
424 return select
? IMFPresentationDescriptor_SelectStream(item
->pd
, index
) :
425 IMFPresentationDescriptor_DeselectStream(item
->pd
, index
);
428 static HRESULT WINAPI
media_item_GetStreamAttribute(IMFPMediaItem
*iface
, DWORD index
, REFGUID key
,
431 struct media_item
*item
= impl_from_IMFPMediaItem(iface
);
432 IMFStreamDescriptor
*sd
;
436 TRACE("%p, %u, %s, %p.\n", iface
, index
, debugstr_guid(key
), value
);
438 if (SUCCEEDED(hr
= IMFPresentationDescriptor_GetStreamDescriptorByIndex(item
->pd
, index
, &selected
, &sd
)))
440 hr
= IMFStreamDescriptor_GetItem(sd
, key
, value
);
441 IMFStreamDescriptor_Release(sd
);
447 static HRESULT WINAPI
media_item_GetPresentationAttribute(IMFPMediaItem
*iface
, REFGUID key
,
450 struct media_item
*item
= impl_from_IMFPMediaItem(iface
);
452 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
454 return IMFPresentationDescriptor_GetItem(item
->pd
, key
, value
);
457 static HRESULT WINAPI
media_item_GetCharacteristics(IMFPMediaItem
*iface
, MFP_MEDIAITEM_CHARACTERISTICS
*flags
)
459 struct media_item
*item
= impl_from_IMFPMediaItem(iface
);
462 TRACE("%p, %p.\n", iface
, flags
);
466 if (SUCCEEDED(hr
= IMFMediaSource_GetCharacteristics(item
->source
, flags
)))
468 *flags
&= (MFP_MEDIAITEM_IS_LIVE
| MFP_MEDIAITEM_CAN_SEEK
|
469 MFP_MEDIAITEM_CAN_PAUSE
| MFP_MEDIAITEM_HAS_SLOW_SEEK
);
475 static HRESULT WINAPI
media_item_SetStreamSink(IMFPMediaItem
*iface
, DWORD index
, IUnknown
*sink
)
477 FIXME("%p, %u, %p.\n", iface
, index
, sink
);
482 static HRESULT WINAPI
media_item_GetMetadata(IMFPMediaItem
*iface
, IPropertyStore
**metadata
)
484 FIXME("%p, %p.\n", iface
, metadata
);
489 static const IMFPMediaItemVtbl media_item_vtbl
=
491 media_item_QueryInterface
,
494 media_item_GetMediaPlayer
,
496 media_item_GetObject
,
497 media_item_GetUserData
,
498 media_item_SetUserData
,
499 media_item_GetStartStopPosition
,
500 media_item_SetStartStopPosition
,
503 media_item_IsProtected
,
504 media_item_GetDuration
,
505 media_item_GetNumberOfStreams
,
506 media_item_GetStreamSelection
,
507 media_item_SetStreamSelection
,
508 media_item_GetStreamAttribute
,
509 media_item_GetPresentationAttribute
,
510 media_item_GetCharacteristics
,
511 media_item_SetStreamSink
,
512 media_item_GetMetadata
,
515 static HRESULT
create_media_item(IMFPMediaPlayer
*player
, DWORD_PTR user_data
, struct media_item
**item
)
517 struct media_item
*object
;
519 if (!(object
= heap_alloc_zero(sizeof(*object
))))
520 return E_OUTOFMEMORY
;
522 object
->IMFPMediaItem_iface
.lpVtbl
= &media_item_vtbl
;
523 object
->refcount
= 1;
524 object
->user_data
= user_data
;
525 object
->player
= player
;
526 IMFPMediaPlayer_AddRef(object
->player
);
533 static HRESULT
media_item_set_source(struct media_item
*item
, IUnknown
*object
)
535 IMFPresentationDescriptor
*pd
;
536 IMFMediaSource
*source
;
539 if (FAILED(hr
= IUnknown_QueryInterface(object
, &IID_IMFMediaSource
, (void **)&source
)))
542 if (FAILED(hr
= IMFMediaSource_CreatePresentationDescriptor(source
, &pd
)))
544 WARN("Failed to get presentation descriptor, hr %#x.\n", hr
);
545 IMFMediaSource_Release(source
);
549 item
->source
= source
;
555 static void media_player_queue_event(struct media_player
*player
, struct media_event
*event
)
557 if (player
->options
& MFP_OPTION_FREE_THREADED_CALLBACK
)
559 MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_MULTITHREADED
, &player
->events_callback
, &event
->IUnknown_iface
);
563 IUnknown_AddRef(&event
->IUnknown_iface
);
564 PostMessageW(player
->event_window
, WM_USER
, 0, (LPARAM
)event
);
568 static HRESULT WINAPI
media_player_QueryInterface(IMFPMediaPlayer
*iface
, REFIID riid
, void **obj
)
570 struct media_player
*player
= impl_from_IMFPMediaPlayer(iface
);
572 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
574 if (IsEqualIID(riid
, &IID_IMFPMediaPlayer
) ||
575 IsEqualIID(riid
, &IID_IUnknown
))
577 *obj
= &player
->IMFPMediaPlayer_iface
;
579 else if (IsEqualIID(riid
, &IID_IPropertyStore
))
581 *obj
= &player
->IPropertyStore_iface
;
585 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
588 return E_NOINTERFACE
;
591 IUnknown_AddRef((IUnknown
*)*obj
);
595 static ULONG WINAPI
media_player_AddRef(IMFPMediaPlayer
*iface
)
597 struct media_player
*player
= impl_from_IMFPMediaPlayer(iface
);
598 ULONG refcount
= InterlockedIncrement(&player
->refcount
);
600 TRACE("%p, refcount %u.\n", iface
, refcount
);
605 static ULONG WINAPI
media_player_Release(IMFPMediaPlayer
*iface
)
607 struct media_player
*player
= impl_from_IMFPMediaPlayer(iface
);
608 ULONG refcount
= InterlockedDecrement(&player
->refcount
);
610 TRACE("%p, refcount %u.\n", iface
, refcount
);
614 if (player
->callback
)
615 IMFPMediaPlayerCallback_Release(player
->callback
);
616 if (player
->propstore
)
617 IPropertyStore_Release(player
->propstore
);
618 if (player
->resolver
)
619 IMFSourceResolver_Release(player
->resolver
);
620 DestroyWindow(player
->event_window
);
629 static HRESULT WINAPI
media_player_Play(IMFPMediaPlayer
*iface
)
631 FIXME("%p.\n", iface
);
636 static HRESULT WINAPI
media_player_Pause(IMFPMediaPlayer
*iface
)
638 FIXME("%p.\n", iface
);
643 static HRESULT WINAPI
media_player_Stop(IMFPMediaPlayer
*iface
)
645 FIXME("%p.\n", iface
);
650 static HRESULT WINAPI
media_player_FrameStep(IMFPMediaPlayer
*iface
)
652 FIXME("%p.\n", iface
);
657 static HRESULT WINAPI
media_player_SetPosition(IMFPMediaPlayer
*iface
, REFGUID postype
, const PROPVARIANT
*position
)
659 FIXME("%p, %s, %p.\n", iface
, debugstr_guid(postype
), position
);
664 static HRESULT WINAPI
media_player_GetPosition(IMFPMediaPlayer
*iface
, REFGUID postype
, PROPVARIANT
*position
)
666 FIXME("%p, %s, %p.\n", iface
, debugstr_guid(postype
), position
);
671 static HRESULT WINAPI
media_player_GetDuration(IMFPMediaPlayer
*iface
, REFGUID postype
, PROPVARIANT
*position
)
673 FIXME("%p, %s, %p.\n", iface
, debugstr_guid(postype
), position
);
678 static HRESULT WINAPI
media_player_SetRate(IMFPMediaPlayer
*iface
, float rate
)
680 FIXME("%p, %f.\n", iface
, rate
);
685 static HRESULT WINAPI
media_player_GetRate(IMFPMediaPlayer
*iface
, float *rate
)
687 FIXME("%p, %p.\n", iface
, rate
);
692 static HRESULT WINAPI
media_player_GetSupportedRates(IMFPMediaPlayer
*iface
, BOOL forward
, float *slowest_rate
, float *fastest_rate
)
694 FIXME("%p, %d, %p, %p.\n", iface
, forward
, slowest_rate
, fastest_rate
);
699 static HRESULT WINAPI
media_player_GetState(IMFPMediaPlayer
*iface
, MFP_MEDIAPLAYER_STATE
*state
)
701 FIXME("%p, %p.\n", iface
, state
);
706 static HRESULT WINAPI
media_player_CreateMediaItemFromURL(IMFPMediaPlayer
*iface
,
707 const WCHAR
*url
, BOOL sync
, DWORD_PTR user_data
, IMFPMediaItem
**ret
)
709 struct media_player
*player
= impl_from_IMFPMediaPlayer(iface
);
710 struct media_item
*item
;
711 MF_OBJECT_TYPE obj_type
;
715 TRACE("%p, %s, %d, %lx, %p.\n", iface
, debugstr_w(url
), sync
, user_data
, ret
);
717 if (FAILED(hr
= create_media_item(iface
, user_data
, &item
)))
724 if (SUCCEEDED(hr
= IMFSourceResolver_CreateObjectFromURL(player
->resolver
, url
, MF_RESOLUTION_MEDIASOURCE
,
725 player
->propstore
, &obj_type
, &object
)))
727 hr
= media_item_set_source(item
, object
);
728 IUnknown_Release(object
);
732 *ret
= &item
->IMFPMediaItem_iface
;
738 hr
= IMFSourceResolver_BeginCreateObjectFromURL(player
->resolver
, url
, MF_RESOLUTION_MEDIASOURCE
,
739 player
->propstore
, NULL
, &player
->resolver_callback
, (IUnknown
*)&item
->IMFPMediaItem_iface
);
741 IMFPMediaItem_Release(&item
->IMFPMediaItem_iface
);
747 static HRESULT WINAPI
media_player_CreateMediaItemFromObject(IMFPMediaPlayer
*iface
,
748 IUnknown
*object
, BOOL sync
, DWORD_PTR user_data
, IMFPMediaItem
**item
)
750 FIXME("%p, %p, %d, %lx, %p.\n", iface
, object
, sync
, user_data
, item
);
755 static HRESULT WINAPI
media_player_SetMediaItem(IMFPMediaPlayer
*iface
, IMFPMediaItem
*item
)
757 FIXME("%p, %p.\n", iface
, item
);
762 static HRESULT WINAPI
media_player_ClearMediaItem(IMFPMediaPlayer
*iface
)
764 FIXME("%p.\n", iface
);
769 static HRESULT WINAPI
media_player_GetMediaItem(IMFPMediaPlayer
*iface
, IMFPMediaItem
**item
)
771 FIXME("%p, %p.\n", iface
, item
);
776 static HRESULT WINAPI
media_player_GetVolume(IMFPMediaPlayer
*iface
, float *volume
)
778 FIXME("%p, %p.\n", iface
, volume
);
783 static HRESULT WINAPI
media_player_SetVolume(IMFPMediaPlayer
*iface
, float volume
)
785 FIXME("%p, %.8e.\n", iface
, volume
);
790 static HRESULT WINAPI
media_player_GetBalance(IMFPMediaPlayer
*iface
, float *balance
)
792 FIXME("%p, %p.\n", iface
, balance
);
797 static HRESULT WINAPI
media_player_SetBalance(IMFPMediaPlayer
*iface
, float balance
)
799 FIXME("%p, %.8e.\n", iface
, balance
);
804 static HRESULT WINAPI
media_player_GetMute(IMFPMediaPlayer
*iface
, BOOL
*mute
)
806 FIXME("%p, %p.\n", iface
, mute
);
811 static HRESULT WINAPI
media_player_SetMute(IMFPMediaPlayer
*iface
, BOOL mute
)
813 FIXME("%p, %d.\n", iface
, mute
);
818 static HRESULT WINAPI
media_player_GetNativeVideoSize(IMFPMediaPlayer
*iface
,
819 SIZE
*video
, SIZE
*arvideo
)
821 FIXME("%p, %p, %p.\n", iface
, video
, arvideo
);
826 static HRESULT WINAPI
media_player_GetIdealVideoSize(IMFPMediaPlayer
*iface
,
827 SIZE
*min_size
, SIZE
*max_size
)
829 FIXME("%p, %p, %p.\n", iface
, min_size
, max_size
);
834 static HRESULT WINAPI
media_player_SetVideoSourceRect(IMFPMediaPlayer
*iface
,
835 MFVideoNormalizedRect
const *rect
)
837 FIXME("%p, %p.\n", iface
, rect
);
842 static HRESULT WINAPI
media_player_GetVideoSourceRect(IMFPMediaPlayer
*iface
,
843 MFVideoNormalizedRect
*rect
)
845 FIXME("%p, %p.\n", iface
, rect
);
850 static HRESULT WINAPI
media_player_SetAspectRatioMode(IMFPMediaPlayer
*iface
, DWORD mode
)
852 FIXME("%p, %u.\n", iface
, mode
);
857 static HRESULT WINAPI
media_player_GetAspectRatioMode(IMFPMediaPlayer
*iface
,
860 FIXME("%p, %p.\n", iface
, mode
);
865 static HRESULT WINAPI
media_player_GetVideoWindow(IMFPMediaPlayer
*iface
, HWND
*hwnd
)
867 FIXME("%p, %p.\n", iface
, hwnd
);
872 static HRESULT WINAPI
media_player_UpdateVideo(IMFPMediaPlayer
*iface
)
874 FIXME("%p.\n", iface
);
879 static HRESULT WINAPI
media_player_SetBorderColor(IMFPMediaPlayer
*iface
, COLORREF color
)
881 FIXME("%p, %#x.\n", iface
, color
);
886 static HRESULT WINAPI
media_player_GetBorderColor(IMFPMediaPlayer
*iface
, COLORREF
*color
)
888 FIXME("%p, %p.\n", iface
, color
);
893 static HRESULT WINAPI
media_player_InsertEffect(IMFPMediaPlayer
*iface
, IUnknown
*effect
,
896 FIXME("%p, %p, %d.\n", iface
, effect
, optional
);
901 static HRESULT WINAPI
media_player_RemoveEffect(IMFPMediaPlayer
*iface
, IUnknown
*effect
)
903 FIXME("%p, %p.\n", iface
, effect
);
908 static HRESULT WINAPI
media_player_RemoveAllEffects(IMFPMediaPlayer
*iface
)
910 FIXME("%p.\n", iface
);
915 static HRESULT WINAPI
media_player_Shutdown(IMFPMediaPlayer
*iface
)
917 FIXME("%p.\n", iface
);
922 static const IMFPMediaPlayerVtbl media_player_vtbl
=
924 media_player_QueryInterface
,
926 media_player_Release
,
930 media_player_FrameStep
,
931 media_player_SetPosition
,
932 media_player_GetPosition
,
933 media_player_GetDuration
,
934 media_player_SetRate
,
935 media_player_GetRate
,
936 media_player_GetSupportedRates
,
937 media_player_GetState
,
938 media_player_CreateMediaItemFromURL
,
939 media_player_CreateMediaItemFromObject
,
940 media_player_SetMediaItem
,
941 media_player_ClearMediaItem
,
942 media_player_GetMediaItem
,
943 media_player_GetVolume
,
944 media_player_SetVolume
,
945 media_player_GetBalance
,
946 media_player_SetBalance
,
947 media_player_GetMute
,
948 media_player_SetMute
,
949 media_player_GetNativeVideoSize
,
950 media_player_GetIdealVideoSize
,
951 media_player_SetVideoSourceRect
,
952 media_player_GetVideoSourceRect
,
953 media_player_SetAspectRatioMode
,
954 media_player_GetAspectRatioMode
,
955 media_player_GetVideoWindow
,
956 media_player_UpdateVideo
,
957 media_player_SetBorderColor
,
958 media_player_GetBorderColor
,
959 media_player_InsertEffect
,
960 media_player_RemoveEffect
,
961 media_player_RemoveAllEffects
,
962 media_player_Shutdown
,
965 static HRESULT WINAPI
media_player_propstore_QueryInterface(IPropertyStore
*iface
,
966 REFIID riid
, void **obj
)
968 struct media_player
*player
= impl_from_IPropertyStore(iface
);
969 return IMFPMediaPlayer_QueryInterface(&player
->IMFPMediaPlayer_iface
, riid
, obj
);
972 static ULONG WINAPI
media_player_propstore_AddRef(IPropertyStore
*iface
)
974 struct media_player
*player
= impl_from_IPropertyStore(iface
);
975 return IMFPMediaPlayer_AddRef(&player
->IMFPMediaPlayer_iface
);
978 static ULONG WINAPI
media_player_propstore_Release(IPropertyStore
*iface
)
980 struct media_player
*player
= impl_from_IPropertyStore(iface
);
981 return IMFPMediaPlayer_Release(&player
->IMFPMediaPlayer_iface
);
984 static HRESULT WINAPI
media_player_propstore_GetCount(IPropertyStore
*iface
, DWORD
*count
)
986 struct media_player
*player
= impl_from_IPropertyStore(iface
);
988 TRACE("%p, %p.\n", iface
, count
);
990 return IPropertyStore_GetCount(player
->propstore
, count
);
993 static HRESULT WINAPI
media_player_propstore_GetAt(IPropertyStore
*iface
, DWORD prop
, PROPERTYKEY
*key
)
995 struct media_player
*player
= impl_from_IPropertyStore(iface
);
997 TRACE("%p, %u, %p.\n", iface
, prop
, key
);
999 return IPropertyStore_GetAt(player
->propstore
, prop
, key
);
1002 static HRESULT WINAPI
media_player_propstore_GetValue(IPropertyStore
*iface
, REFPROPERTYKEY key
, PROPVARIANT
*value
)
1004 struct media_player
*player
= impl_from_IPropertyStore(iface
);
1006 TRACE("%p, %p, %p.\n", iface
, key
, value
);
1008 return IPropertyStore_GetValue(player
->propstore
, key
, value
);
1011 static HRESULT WINAPI
media_player_propstore_SetValue(IPropertyStore
*iface
, REFPROPERTYKEY key
, REFPROPVARIANT value
)
1013 struct media_player
*player
= impl_from_IPropertyStore(iface
);
1015 TRACE("%p, %p, %p.\n", iface
, key
, value
);
1017 return IPropertyStore_SetValue(player
->propstore
, key
, value
);
1020 static HRESULT WINAPI
media_player_propstore_Commit(IPropertyStore
*iface
)
1022 struct media_player
*player
= impl_from_IPropertyStore(iface
);
1024 TRACE("%p.\n", iface
);
1026 return IPropertyStore_Commit(player
->propstore
);
1029 static const IPropertyStoreVtbl media_player_propstore_vtbl
=
1031 media_player_propstore_QueryInterface
,
1032 media_player_propstore_AddRef
,
1033 media_player_propstore_Release
,
1034 media_player_propstore_GetCount
,
1035 media_player_propstore_GetAt
,
1036 media_player_propstore_GetValue
,
1037 media_player_propstore_SetValue
,
1038 media_player_propstore_Commit
,
1041 static HRESULT WINAPI
media_player_callback_QueryInterface(IMFAsyncCallback
*iface
,
1042 REFIID riid
, void **obj
)
1044 if (IsEqualIID(riid
, &IID_IMFAsyncCallback
) ||
1045 IsEqualIID(riid
, &IID_IUnknown
))
1048 IMFAsyncCallback_AddRef(iface
);
1053 return E_NOINTERFACE
;
1056 static ULONG WINAPI
media_player_resolver_callback_AddRef(IMFAsyncCallback
*iface
)
1058 struct media_player
*player
= impl_from_resolver_IMFAsyncCallback(iface
);
1059 return IMFPMediaPlayer_AddRef(&player
->IMFPMediaPlayer_iface
);
1062 static ULONG WINAPI
media_player_resolver_callback_Release(IMFAsyncCallback
*iface
)
1064 struct media_player
*player
= impl_from_resolver_IMFAsyncCallback(iface
);
1065 return IMFPMediaPlayer_Release(&player
->IMFPMediaPlayer_iface
);
1068 static HRESULT WINAPI
media_player_callback_GetParameters(IMFAsyncCallback
*iface
, DWORD
*flags
,
1074 static HRESULT WINAPI
media_player_resolver_callback_Invoke(IMFAsyncCallback
*iface
, IMFAsyncResult
*result
)
1076 struct media_player
*player
= impl_from_resolver_IMFAsyncCallback(iface
);
1077 struct media_event
*event
;
1078 IUnknown
*object
, *state
;
1079 MF_OBJECT_TYPE obj_type
;
1080 struct media_item
*item
;
1083 if (FAILED(IMFAsyncResult_GetState(result
, &state
)))
1086 item
= impl_from_IMFPMediaItem((IMFPMediaItem
*)state
);
1088 if (SUCCEEDED(hr
= IMFSourceResolver_EndCreateObjectFromURL(player
->resolver
, result
, &obj_type
, &object
)))
1090 hr
= media_item_set_source(item
, object
);
1091 IUnknown_Release(object
);
1095 WARN("Failed to set media source, hr %#x.\n", hr
);
1097 if (FAILED(media_event_create(MFP_EVENT_TYPE_MEDIAITEM_CREATED
, hr
, &player
->IMFPMediaPlayer_iface
, &event
)))
1099 WARN("Failed to create event object.\n");
1100 IUnknown_Release(state
);
1106 event
->u
.item_created
.pMediaItem
= &item
->IMFPMediaItem_iface
;
1107 IMFPMediaItem_AddRef(event
->u
.item_created
.pMediaItem
);
1109 event
->u
.item_created
.dwUserData
= item
->user_data
;
1111 media_player_queue_event(player
, event
);
1113 IUnknown_Release(&event
->IUnknown_iface
);
1114 IUnknown_Release(state
);
1119 static const IMFAsyncCallbackVtbl media_player_resolver_callback_vtbl
=
1121 media_player_callback_QueryInterface
,
1122 media_player_resolver_callback_AddRef
,
1123 media_player_resolver_callback_Release
,
1124 media_player_callback_GetParameters
,
1125 media_player_resolver_callback_Invoke
,
1128 static ULONG WINAPI
media_player_events_callback_AddRef(IMFAsyncCallback
*iface
)
1130 struct media_player
*player
= impl_from_events_IMFAsyncCallback(iface
);
1131 return IMFPMediaPlayer_AddRef(&player
->IMFPMediaPlayer_iface
);
1134 static ULONG WINAPI
media_player_events_callback_Release(IMFAsyncCallback
*iface
)
1136 struct media_player
*player
= impl_from_events_IMFAsyncCallback(iface
);
1137 return IMFPMediaPlayer_Release(&player
->IMFPMediaPlayer_iface
);
1140 static HRESULT WINAPI
media_player_events_callback_Invoke(IMFAsyncCallback
*iface
, IMFAsyncResult
*result
)
1142 struct media_player
*player
= impl_from_events_IMFAsyncCallback(iface
);
1143 struct media_event
*event
;
1146 if (FAILED(IMFAsyncResult_GetState(result
, &state
)))
1149 event
= impl_event_from_IUnknown(state
);
1151 if (player
->callback
)
1152 IMFPMediaPlayerCallback_OnMediaPlayerEvent(player
->callback
, &event
->u
.header
);
1154 IUnknown_Release(state
);
1159 static const IMFAsyncCallbackVtbl media_player_events_callback_vtbl
=
1161 media_player_callback_QueryInterface
,
1162 media_player_events_callback_AddRef
,
1163 media_player_events_callback_Release
,
1164 media_player_callback_GetParameters
,
1165 media_player_events_callback_Invoke
,
1168 HRESULT WINAPI
MFPCreateMediaPlayer(const WCHAR
*url
, BOOL start_playback
, MFP_CREATION_OPTIONS options
,
1169 IMFPMediaPlayerCallback
*callback
, HWND hwnd
, IMFPMediaPlayer
**player
)
1171 struct media_player
*object
;
1174 TRACE("%s, %d, %#x, %p, %p, %p.\n", debugstr_w(url
), start_playback
, options
, callback
, hwnd
, player
);
1176 if (!(object
= heap_alloc_zero(sizeof(*object
))))
1177 return E_OUTOFMEMORY
;
1181 object
->IMFPMediaPlayer_iface
.lpVtbl
= &media_player_vtbl
;
1182 object
->IPropertyStore_iface
.lpVtbl
= &media_player_propstore_vtbl
;
1183 object
->resolver_callback
.lpVtbl
= &media_player_resolver_callback_vtbl
;
1184 object
->events_callback
.lpVtbl
= &media_player_events_callback_vtbl
;
1185 object
->refcount
= 1;
1186 object
->callback
= callback
;
1187 object
->options
= options
;
1188 if (object
->callback
)
1189 IMFPMediaPlayerCallback_AddRef(object
->callback
);
1190 if (FAILED(hr
= CreatePropertyStore(&object
->propstore
)))
1192 if (FAILED(hr
= MFCreateSourceResolver(&object
->resolver
)))
1194 if (!(object
->options
& MFP_OPTION_FREE_THREADED_CALLBACK
))
1196 object
->event_window
= CreateWindowW(eventclassW
, NULL
, 0, 0, 0, 0, 0, HWND_MESSAGE
,
1197 0, mfplay_instance
, NULL
);
1200 *player
= &object
->IMFPMediaPlayer_iface
;
1206 IMFPMediaPlayer_Release(&object
->IMFPMediaPlayer_iface
);
1211 static void media_player_register_window_class(void)
1213 WNDCLASSW cls
= { 0 };
1215 cls
.lpfnWndProc
= media_player_event_proc
;
1216 cls
.hInstance
= mfplay_instance
;
1217 cls
.lpszClassName
= eventclassW
;
1219 RegisterClassW(&cls
);
1222 BOOL WINAPI
DllMain(HINSTANCE instance
, DWORD reason
, void *reserved
)
1226 case DLL_PROCESS_ATTACH
:
1227 mfplay_instance
= instance
;
1228 DisableThreadLibraryCalls(instance
);
1229 media_player_register_window_class();
1231 case DLL_PROCESS_DETACH
:
1232 if (reserved
) break;
1233 UnregisterClassW(eventclassW
, instance
);