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 LONG startup_refcount
;
35 static void platform_startup(void)
37 if (InterlockedIncrement(&startup_refcount
) == 1)
38 MFStartup(MF_VERSION
, MFSTARTUP_FULL
);
41 static void platform_shutdown(void)
43 if (InterlockedDecrement(&startup_refcount
) == 0)
49 IMFPMediaItem IMFPMediaItem_iface
;
51 IMFPMediaPlayer
*player
;
52 IMFMediaSource
*source
;
53 IMFPresentationDescriptor
*pd
;
59 IMFPMediaPlayer IMFPMediaPlayer_iface
;
60 IPropertyStore IPropertyStore_iface
;
61 IMFAsyncCallback resolver_callback
;
63 IMFPMediaPlayerCallback
*callback
;
64 IPropertyStore
*propstore
;
65 IMFSourceResolver
*resolver
;
68 static struct media_player
*impl_from_IMFPMediaPlayer(IMFPMediaPlayer
*iface
)
70 return CONTAINING_RECORD(iface
, struct media_player
, IMFPMediaPlayer_iface
);
73 static struct media_player
*impl_from_IPropertyStore(IPropertyStore
*iface
)
75 return CONTAINING_RECORD(iface
, struct media_player
, IPropertyStore_iface
);
78 static struct media_player
*impl_from_resolver_IMFAsyncCallback(IMFAsyncCallback
*iface
)
80 return CONTAINING_RECORD(iface
, struct media_player
, resolver_callback
);
83 static struct media_item
*impl_from_IMFPMediaItem(IMFPMediaItem
*iface
)
85 return CONTAINING_RECORD(iface
, struct media_item
, IMFPMediaItem_iface
);
88 static HRESULT WINAPI
media_item_QueryInterface(IMFPMediaItem
*iface
, REFIID riid
, void **obj
)
90 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
92 if (IsEqualIID(riid
, &IID_IMFPMediaItem
) ||
93 IsEqualIID(riid
, &IID_IUnknown
))
96 IMFPMediaItem_AddRef(iface
);
100 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
102 return E_NOINTERFACE
;
105 static ULONG WINAPI
media_item_AddRef(IMFPMediaItem
*iface
)
107 struct media_item
*item
= impl_from_IMFPMediaItem(iface
);
108 ULONG refcount
= InterlockedIncrement(&item
->refcount
);
110 TRACE("%p, refcount %u.\n", iface
, refcount
);
115 static ULONG WINAPI
media_item_Release(IMFPMediaItem
*iface
)
117 struct media_item
*item
= impl_from_IMFPMediaItem(iface
);
118 ULONG refcount
= InterlockedDecrement(&item
->refcount
);
120 TRACE("%p, refcount %u.\n", iface
, refcount
);
125 IMFPMediaPlayer_Release(item
->player
);
127 IMFMediaSource_Release(item
->source
);
129 IMFPresentationDescriptor_Release(item
->pd
);
136 static HRESULT WINAPI
media_item_GetMediaPlayer(IMFPMediaItem
*iface
,
137 IMFPMediaPlayer
**player
)
139 struct media_item
*item
= impl_from_IMFPMediaItem(iface
);
141 TRACE("%p, %p.\n", iface
, player
);
143 *player
= item
->player
;
144 IMFPMediaPlayer_AddRef(*player
);
149 static HRESULT WINAPI
media_item_GetURL(IMFPMediaItem
*iface
, LPWSTR
*url
)
151 FIXME("%p, %p.\n", iface
, url
);
156 static HRESULT WINAPI
media_item_GetObject(IMFPMediaItem
*iface
, IUnknown
**obj
)
158 FIXME("%p, %p.\n", iface
, obj
);
163 static HRESULT WINAPI
media_item_GetUserData(IMFPMediaItem
*iface
, DWORD_PTR
*user_data
)
165 struct media_item
*item
= impl_from_IMFPMediaItem(iface
);
167 TRACE("%p, %p.\n", iface
, user_data
);
169 *user_data
= item
->user_data
;
174 static HRESULT WINAPI
media_item_SetUserData(IMFPMediaItem
*iface
, DWORD_PTR user_data
)
176 struct media_item
*item
= impl_from_IMFPMediaItem(iface
);
178 TRACE("%p, %lx.\n", iface
, user_data
);
180 item
->user_data
= user_data
;
185 static HRESULT WINAPI
media_item_GetStartStopPosition(IMFPMediaItem
*iface
, GUID
*start_format
,
186 PROPVARIANT
*start_position
, GUID
*stop_format
, PROPVARIANT
*stop_position
)
188 FIXME("%p, %p, %p, %p, %p.\n", iface
, start_format
, start_position
, stop_format
, stop_position
);
193 static HRESULT WINAPI
media_item_SetStartStopPosition(IMFPMediaItem
*iface
, const GUID
*start_format
,
194 const PROPVARIANT
*start_position
, const GUID
*stop_format
, const PROPVARIANT
*stop_position
)
196 FIXME("%p, %s, %p, %s, %p.\n", iface
, debugstr_guid(start_format
), start_position
,
197 debugstr_guid(stop_format
), stop_position
);
202 static HRESULT WINAPI
media_item_HasVideo(IMFPMediaItem
*iface
, BOOL
*has_video
, BOOL
*selected
)
204 FIXME("%p, %p, %p.\n", iface
, has_video
, selected
);
209 static HRESULT WINAPI
media_item_HasAudio(IMFPMediaItem
*iface
, BOOL
*has_audio
, BOOL
*selected
)
211 FIXME("%p, %p, %p.\n", iface
, has_audio
, selected
);
216 static HRESULT WINAPI
media_item_IsProtected(IMFPMediaItem
*iface
, BOOL
*protected)
218 struct media_item
*item
= impl_from_IMFPMediaItem(iface
);
220 TRACE("%p, %p.\n", iface
, protected);
222 *protected = MFRequireProtectedEnvironment(item
->pd
) == S_OK
;
227 static HRESULT WINAPI
media_item_GetDuration(IMFPMediaItem
*iface
, REFGUID format
, PROPVARIANT
*value
)
229 FIXME("%p, %s, %p.\n", iface
, debugstr_guid(format
), value
);
234 static HRESULT WINAPI
media_item_GetNumberOfStreams(IMFPMediaItem
*iface
, DWORD
*count
)
236 struct media_item
*item
= impl_from_IMFPMediaItem(iface
);
238 TRACE("%p, %p.\n", iface
, count
);
240 return IMFPresentationDescriptor_GetStreamDescriptorCount(item
->pd
, count
);
243 static HRESULT WINAPI
media_item_GetStreamSelection(IMFPMediaItem
*iface
, DWORD index
, BOOL
*selected
)
245 struct media_item
*item
= impl_from_IMFPMediaItem(iface
);
246 IMFStreamDescriptor
*sd
;
249 TRACE("%p, %u, %p.\n", iface
, index
, selected
);
251 if (SUCCEEDED(hr
= IMFPresentationDescriptor_GetStreamDescriptorByIndex(item
->pd
, index
, selected
, &sd
)))
252 IMFStreamDescriptor_Release(sd
);
257 static HRESULT WINAPI
media_item_SetStreamSelection(IMFPMediaItem
*iface
, DWORD index
, BOOL select
)
259 struct media_item
*item
= impl_from_IMFPMediaItem(iface
);
261 TRACE("%p, %u, %d.\n", iface
, index
, select
);
263 return select
? IMFPresentationDescriptor_SelectStream(item
->pd
, index
) :
264 IMFPresentationDescriptor_DeselectStream(item
->pd
, index
);
267 static HRESULT WINAPI
media_item_GetStreamAttribute(IMFPMediaItem
*iface
, DWORD index
, REFGUID key
,
270 struct media_item
*item
= impl_from_IMFPMediaItem(iface
);
271 IMFStreamDescriptor
*sd
;
275 TRACE("%p, %u, %s, %p.\n", iface
, index
, debugstr_guid(key
), value
);
277 if (SUCCEEDED(hr
= IMFPresentationDescriptor_GetStreamDescriptorByIndex(item
->pd
, index
, &selected
, &sd
)))
279 hr
= IMFStreamDescriptor_GetItem(sd
, key
, value
);
280 IMFStreamDescriptor_Release(sd
);
286 static HRESULT WINAPI
media_item_GetPresentationAttribute(IMFPMediaItem
*iface
, REFGUID key
,
289 struct media_item
*item
= impl_from_IMFPMediaItem(iface
);
291 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(key
), value
);
293 return IMFPresentationDescriptor_GetItem(item
->pd
, key
, value
);
296 static HRESULT WINAPI
media_item_GetCharacteristics(IMFPMediaItem
*iface
, MFP_MEDIAITEM_CHARACTERISTICS
*flags
)
298 FIXME("%p, %p.\n", iface
, flags
);
303 static HRESULT WINAPI
media_item_SetStreamSink(IMFPMediaItem
*iface
, DWORD index
, IUnknown
*sink
)
305 FIXME("%p, %u, %p.\n", iface
, index
, sink
);
310 static HRESULT WINAPI
media_item_GetMetadata(IMFPMediaItem
*iface
, IPropertyStore
**metadata
)
312 FIXME("%p, %p.\n", iface
, metadata
);
317 static const IMFPMediaItemVtbl media_item_vtbl
=
319 media_item_QueryInterface
,
322 media_item_GetMediaPlayer
,
324 media_item_GetObject
,
325 media_item_GetUserData
,
326 media_item_SetUserData
,
327 media_item_GetStartStopPosition
,
328 media_item_SetStartStopPosition
,
331 media_item_IsProtected
,
332 media_item_GetDuration
,
333 media_item_GetNumberOfStreams
,
334 media_item_GetStreamSelection
,
335 media_item_SetStreamSelection
,
336 media_item_GetStreamAttribute
,
337 media_item_GetPresentationAttribute
,
338 media_item_GetCharacteristics
,
339 media_item_SetStreamSink
,
340 media_item_GetMetadata
,
343 static HRESULT
create_media_item(IMFPMediaPlayer
*player
, DWORD_PTR user_data
, struct media_item
**item
)
345 struct media_item
*object
;
347 if (!(object
= heap_alloc_zero(sizeof(*object
))))
348 return E_OUTOFMEMORY
;
350 object
->IMFPMediaItem_iface
.lpVtbl
= &media_item_vtbl
;
351 object
->refcount
= 1;
352 object
->user_data
= user_data
;
353 object
->player
= player
;
354 IMFPMediaPlayer_AddRef(object
->player
);
361 static HRESULT
media_item_set_source(struct media_item
*item
, IUnknown
*object
)
363 IMFPresentationDescriptor
*pd
;
364 IMFMediaSource
*source
;
367 if (FAILED(hr
= IUnknown_QueryInterface(object
, &IID_IMFMediaSource
, (void **)&source
)))
370 if (FAILED(hr
= IMFMediaSource_CreatePresentationDescriptor(source
, &pd
)))
372 WARN("Failed to get presentation descriptor, hr %#x.\n", hr
);
373 IMFMediaSource_Release(source
);
377 item
->source
= source
;
383 static HRESULT WINAPI
media_player_QueryInterface(IMFPMediaPlayer
*iface
, REFIID riid
, void **obj
)
385 struct media_player
*player
= impl_from_IMFPMediaPlayer(iface
);
387 TRACE("%p, %s, %p.\n", iface
, debugstr_guid(riid
), obj
);
389 if (IsEqualIID(riid
, &IID_IMFPMediaPlayer
) ||
390 IsEqualIID(riid
, &IID_IUnknown
))
392 *obj
= &player
->IMFPMediaPlayer_iface
;
394 else if (IsEqualIID(riid
, &IID_IPropertyStore
))
396 *obj
= &player
->IPropertyStore_iface
;
400 WARN("Unsupported interface %s.\n", debugstr_guid(riid
));
403 return E_NOINTERFACE
;
406 IUnknown_AddRef((IUnknown
*)*obj
);
410 static ULONG WINAPI
media_player_AddRef(IMFPMediaPlayer
*iface
)
412 struct media_player
*player
= impl_from_IMFPMediaPlayer(iface
);
413 ULONG refcount
= InterlockedIncrement(&player
->refcount
);
415 TRACE("%p, refcount %u.\n", iface
, refcount
);
420 static ULONG WINAPI
media_player_Release(IMFPMediaPlayer
*iface
)
422 struct media_player
*player
= impl_from_IMFPMediaPlayer(iface
);
423 ULONG refcount
= InterlockedDecrement(&player
->refcount
);
425 TRACE("%p, refcount %u.\n", iface
, refcount
);
429 if (player
->callback
)
430 IMFPMediaPlayerCallback_Release(player
->callback
);
431 if (player
->propstore
)
432 IPropertyStore_Release(player
->propstore
);
433 if (player
->resolver
)
434 IMFSourceResolver_Release(player
->resolver
);
443 static HRESULT WINAPI
media_player_Play(IMFPMediaPlayer
*iface
)
445 FIXME("%p.\n", iface
);
450 static HRESULT WINAPI
media_player_Pause(IMFPMediaPlayer
*iface
)
452 FIXME("%p.\n", iface
);
457 static HRESULT WINAPI
media_player_Stop(IMFPMediaPlayer
*iface
)
459 FIXME("%p.\n", iface
);
464 static HRESULT WINAPI
media_player_FrameStep(IMFPMediaPlayer
*iface
)
466 FIXME("%p.\n", iface
);
471 static HRESULT WINAPI
media_player_SetPosition(IMFPMediaPlayer
*iface
, REFGUID postype
, const PROPVARIANT
*position
)
473 FIXME("%p, %s, %p.\n", iface
, debugstr_guid(postype
), position
);
478 static HRESULT WINAPI
media_player_GetPosition(IMFPMediaPlayer
*iface
, REFGUID postype
, PROPVARIANT
*position
)
480 FIXME("%p, %s, %p.\n", iface
, debugstr_guid(postype
), position
);
485 static HRESULT WINAPI
media_player_GetDuration(IMFPMediaPlayer
*iface
, REFGUID postype
, PROPVARIANT
*position
)
487 FIXME("%p, %s, %p.\n", iface
, debugstr_guid(postype
), position
);
492 static HRESULT WINAPI
media_player_SetRate(IMFPMediaPlayer
*iface
, float rate
)
494 FIXME("%p, %f.\n", iface
, rate
);
499 static HRESULT WINAPI
media_player_GetRate(IMFPMediaPlayer
*iface
, float *rate
)
501 FIXME("%p, %p.\n", iface
, rate
);
506 static HRESULT WINAPI
media_player_GetSupportedRates(IMFPMediaPlayer
*iface
, BOOL forward
, float *slowest_rate
, float *fastest_rate
)
508 FIXME("%p, %d, %p, %p.\n", iface
, forward
, slowest_rate
, fastest_rate
);
513 static HRESULT WINAPI
media_player_GetState(IMFPMediaPlayer
*iface
, MFP_MEDIAPLAYER_STATE
*state
)
515 FIXME("%p, %p.\n", iface
, state
);
520 static HRESULT WINAPI
media_player_CreateMediaItemFromURL(IMFPMediaPlayer
*iface
,
521 const WCHAR
*url
, BOOL sync
, DWORD_PTR user_data
, IMFPMediaItem
**ret
)
523 struct media_player
*player
= impl_from_IMFPMediaPlayer(iface
);
524 struct media_item
*item
;
525 MF_OBJECT_TYPE obj_type
;
529 TRACE("%p, %s, %d, %lx, %p.\n", iface
, debugstr_w(url
), sync
, user_data
, ret
);
531 if (FAILED(hr
= create_media_item(iface
, user_data
, &item
)))
538 if (SUCCEEDED(hr
= IMFSourceResolver_CreateObjectFromURL(player
->resolver
, url
, MF_RESOLUTION_MEDIASOURCE
,
539 player
->propstore
, &obj_type
, &object
)))
541 hr
= media_item_set_source(item
, object
);
542 IUnknown_Release(object
);
546 *ret
= &item
->IMFPMediaItem_iface
;
552 hr
= IMFSourceResolver_BeginCreateObjectFromURL(player
->resolver
, url
, MF_RESOLUTION_MEDIASOURCE
,
553 player
->propstore
, NULL
, &player
->resolver_callback
, (IUnknown
*)&item
->IMFPMediaItem_iface
);
555 IMFPMediaItem_Release(&item
->IMFPMediaItem_iface
);
561 static HRESULT WINAPI
media_player_CreateMediaItemFromObject(IMFPMediaPlayer
*iface
,
562 IUnknown
*object
, BOOL sync
, DWORD_PTR user_data
, IMFPMediaItem
**item
)
564 FIXME("%p, %p, %d, %lx, %p.\n", iface
, object
, sync
, user_data
, item
);
569 static HRESULT WINAPI
media_player_SetMediaItem(IMFPMediaPlayer
*iface
, IMFPMediaItem
*item
)
571 FIXME("%p, %p.\n", iface
, item
);
576 static HRESULT WINAPI
media_player_ClearMediaItem(IMFPMediaPlayer
*iface
)
578 FIXME("%p.\n", iface
);
583 static HRESULT WINAPI
media_player_GetMediaItem(IMFPMediaPlayer
*iface
, IMFPMediaItem
**item
)
585 FIXME("%p, %p.\n", iface
, item
);
590 static HRESULT WINAPI
media_player_GetVolume(IMFPMediaPlayer
*iface
, float *volume
)
592 FIXME("%p, %p.\n", iface
, volume
);
597 static HRESULT WINAPI
media_player_SetVolume(IMFPMediaPlayer
*iface
, float volume
)
599 FIXME("%p, %.8e.\n", iface
, volume
);
604 static HRESULT WINAPI
media_player_GetBalance(IMFPMediaPlayer
*iface
, float *balance
)
606 FIXME("%p, %p.\n", iface
, balance
);
611 static HRESULT WINAPI
media_player_SetBalance(IMFPMediaPlayer
*iface
, float balance
)
613 FIXME("%p, %.8e.\n", iface
, balance
);
618 static HRESULT WINAPI
media_player_GetMute(IMFPMediaPlayer
*iface
, BOOL
*mute
)
620 FIXME("%p, %p.\n", iface
, mute
);
625 static HRESULT WINAPI
media_player_SetMute(IMFPMediaPlayer
*iface
, BOOL mute
)
627 FIXME("%p, %d.\n", iface
, mute
);
632 static HRESULT WINAPI
media_player_GetNativeVideoSize(IMFPMediaPlayer
*iface
,
633 SIZE
*video
, SIZE
*arvideo
)
635 FIXME("%p, %p, %p.\n", iface
, video
, arvideo
);
640 static HRESULT WINAPI
media_player_GetIdealVideoSize(IMFPMediaPlayer
*iface
,
641 SIZE
*min_size
, SIZE
*max_size
)
643 FIXME("%p, %p, %p.\n", iface
, min_size
, max_size
);
648 static HRESULT WINAPI
media_player_SetVideoSourceRect(IMFPMediaPlayer
*iface
,
649 MFVideoNormalizedRect
const *rect
)
651 FIXME("%p, %p.\n", iface
, rect
);
656 static HRESULT WINAPI
media_player_GetVideoSourceRect(IMFPMediaPlayer
*iface
,
657 MFVideoNormalizedRect
*rect
)
659 FIXME("%p, %p.\n", iface
, rect
);
664 static HRESULT WINAPI
media_player_SetAspectRatioMode(IMFPMediaPlayer
*iface
, DWORD mode
)
666 FIXME("%p, %u.\n", iface
, mode
);
671 static HRESULT WINAPI
media_player_GetAspectRatioMode(IMFPMediaPlayer
*iface
,
674 FIXME("%p, %p.\n", iface
, mode
);
679 static HRESULT WINAPI
media_player_GetVideoWindow(IMFPMediaPlayer
*iface
, HWND
*hwnd
)
681 FIXME("%p, %p.\n", iface
, hwnd
);
686 static HRESULT WINAPI
media_player_UpdateVideo(IMFPMediaPlayer
*iface
)
688 FIXME("%p.\n", iface
);
693 static HRESULT WINAPI
media_player_SetBorderColor(IMFPMediaPlayer
*iface
, COLORREF color
)
695 FIXME("%p, %#x.\n", iface
, color
);
700 static HRESULT WINAPI
media_player_GetBorderColor(IMFPMediaPlayer
*iface
, COLORREF
*color
)
702 FIXME("%p, %p.\n", iface
, color
);
707 static HRESULT WINAPI
media_player_InsertEffect(IMFPMediaPlayer
*iface
, IUnknown
*effect
,
710 FIXME("%p, %p, %d.\n", iface
, effect
, optional
);
715 static HRESULT WINAPI
media_player_RemoveEffect(IMFPMediaPlayer
*iface
, IUnknown
*effect
)
717 FIXME("%p, %p.\n", iface
, effect
);
722 static HRESULT WINAPI
media_player_RemoveAllEffects(IMFPMediaPlayer
*iface
)
724 FIXME("%p.\n", iface
);
729 static HRESULT WINAPI
media_player_Shutdown(IMFPMediaPlayer
*iface
)
731 FIXME("%p.\n", iface
);
736 static const IMFPMediaPlayerVtbl media_player_vtbl
=
738 media_player_QueryInterface
,
740 media_player_Release
,
744 media_player_FrameStep
,
745 media_player_SetPosition
,
746 media_player_GetPosition
,
747 media_player_GetDuration
,
748 media_player_SetRate
,
749 media_player_GetRate
,
750 media_player_GetSupportedRates
,
751 media_player_GetState
,
752 media_player_CreateMediaItemFromURL
,
753 media_player_CreateMediaItemFromObject
,
754 media_player_SetMediaItem
,
755 media_player_ClearMediaItem
,
756 media_player_GetMediaItem
,
757 media_player_GetVolume
,
758 media_player_SetVolume
,
759 media_player_GetBalance
,
760 media_player_SetBalance
,
761 media_player_GetMute
,
762 media_player_SetMute
,
763 media_player_GetNativeVideoSize
,
764 media_player_GetIdealVideoSize
,
765 media_player_SetVideoSourceRect
,
766 media_player_GetVideoSourceRect
,
767 media_player_SetAspectRatioMode
,
768 media_player_GetAspectRatioMode
,
769 media_player_GetVideoWindow
,
770 media_player_UpdateVideo
,
771 media_player_SetBorderColor
,
772 media_player_GetBorderColor
,
773 media_player_InsertEffect
,
774 media_player_RemoveEffect
,
775 media_player_RemoveAllEffects
,
776 media_player_Shutdown
,
779 static HRESULT WINAPI
media_player_propstore_QueryInterface(IPropertyStore
*iface
,
780 REFIID riid
, void **obj
)
782 struct media_player
*player
= impl_from_IPropertyStore(iface
);
783 return IMFPMediaPlayer_QueryInterface(&player
->IMFPMediaPlayer_iface
, riid
, obj
);
786 static ULONG WINAPI
media_player_propstore_AddRef(IPropertyStore
*iface
)
788 struct media_player
*player
= impl_from_IPropertyStore(iface
);
789 return IMFPMediaPlayer_AddRef(&player
->IMFPMediaPlayer_iface
);
792 static ULONG WINAPI
media_player_propstore_Release(IPropertyStore
*iface
)
794 struct media_player
*player
= impl_from_IPropertyStore(iface
);
795 return IMFPMediaPlayer_Release(&player
->IMFPMediaPlayer_iface
);
798 static HRESULT WINAPI
media_player_propstore_GetCount(IPropertyStore
*iface
, DWORD
*count
)
800 struct media_player
*player
= impl_from_IPropertyStore(iface
);
802 TRACE("%p, %p.\n", iface
, count
);
804 return IPropertyStore_GetCount(player
->propstore
, count
);
807 static HRESULT WINAPI
media_player_propstore_GetAt(IPropertyStore
*iface
, DWORD prop
, PROPERTYKEY
*key
)
809 struct media_player
*player
= impl_from_IPropertyStore(iface
);
811 TRACE("%p, %u, %p.\n", iface
, prop
, key
);
813 return IPropertyStore_GetAt(player
->propstore
, prop
, key
);
816 static HRESULT WINAPI
media_player_propstore_GetValue(IPropertyStore
*iface
, REFPROPERTYKEY key
, PROPVARIANT
*value
)
818 struct media_player
*player
= impl_from_IPropertyStore(iface
);
820 TRACE("%p, %p, %p.\n", iface
, key
, value
);
822 return IPropertyStore_GetValue(player
->propstore
, key
, value
);
825 static HRESULT WINAPI
media_player_propstore_SetValue(IPropertyStore
*iface
, REFPROPERTYKEY key
, REFPROPVARIANT value
)
827 struct media_player
*player
= impl_from_IPropertyStore(iface
);
829 TRACE("%p, %p, %p.\n", iface
, key
, value
);
831 return IPropertyStore_SetValue(player
->propstore
, key
, value
);
834 static HRESULT WINAPI
media_player_propstore_Commit(IPropertyStore
*iface
)
836 struct media_player
*player
= impl_from_IPropertyStore(iface
);
838 TRACE("%p.\n", iface
);
840 return IPropertyStore_Commit(player
->propstore
);
843 static const IPropertyStoreVtbl media_player_propstore_vtbl
=
845 media_player_propstore_QueryInterface
,
846 media_player_propstore_AddRef
,
847 media_player_propstore_Release
,
848 media_player_propstore_GetCount
,
849 media_player_propstore_GetAt
,
850 media_player_propstore_GetValue
,
851 media_player_propstore_SetValue
,
852 media_player_propstore_Commit
,
855 static HRESULT WINAPI
media_player_resolver_callback_QueryInterface(IMFAsyncCallback
*iface
,
856 REFIID riid
, void **obj
)
858 if (IsEqualIID(riid
, &IID_IMFAsyncCallback
) ||
859 IsEqualIID(riid
, &IID_IUnknown
))
862 IMFAsyncCallback_AddRef(iface
);
867 return E_NOINTERFACE
;
870 static ULONG WINAPI
media_player_resolver_callback_AddRef(IMFAsyncCallback
*iface
)
872 struct media_player
*player
= impl_from_resolver_IMFAsyncCallback(iface
);
873 return IMFPMediaPlayer_AddRef(&player
->IMFPMediaPlayer_iface
);
876 static ULONG WINAPI
media_player_resolver_callback_Release(IMFAsyncCallback
*iface
)
878 struct media_player
*player
= impl_from_resolver_IMFAsyncCallback(iface
);
879 return IMFPMediaPlayer_Release(&player
->IMFPMediaPlayer_iface
);
882 static HRESULT WINAPI
media_player_resolver_callback_GetParameters(IMFAsyncCallback
*iface
, DWORD
*flags
,
888 static HRESULT WINAPI
media_player_resolver_callback_Invoke(IMFAsyncCallback
*iface
, IMFAsyncResult
*result
)
890 struct media_player
*player
= impl_from_resolver_IMFAsyncCallback(iface
);
891 struct media_item
*item
;
892 IUnknown
*object
, *state
;
893 MF_OBJECT_TYPE obj_type
;
896 if (FAILED(IMFAsyncResult_GetState(result
, &state
)))
899 item
= impl_from_IMFPMediaItem((IMFPMediaItem
*)state
);
901 if (SUCCEEDED(hr
= IMFSourceResolver_EndCreateObjectFromURL(player
->resolver
, result
, &obj_type
, &object
)))
903 hr
= media_item_set_source(item
, object
);
904 IUnknown_Release(object
);
908 WARN("Failed to set media source, hr %#x.\n", hr
);
910 /* FIXME: callback notification */
912 IUnknown_Release(state
);
917 static const IMFAsyncCallbackVtbl media_player_resolver_callback_vtbl
=
919 media_player_resolver_callback_QueryInterface
,
920 media_player_resolver_callback_AddRef
,
921 media_player_resolver_callback_Release
,
922 media_player_resolver_callback_GetParameters
,
923 media_player_resolver_callback_Invoke
,
926 HRESULT WINAPI
MFPCreateMediaPlayer(const WCHAR
*url
, BOOL start_playback
, MFP_CREATION_OPTIONS options
,
927 IMFPMediaPlayerCallback
*callback
, HWND hwnd
, IMFPMediaPlayer
**player
)
929 struct media_player
*object
;
932 TRACE("%s, %d, %#x, %p, %p, %p.\n", debugstr_w(url
), start_playback
, options
, callback
, hwnd
, player
);
934 if (!(object
= heap_alloc_zero(sizeof(*object
))))
935 return E_OUTOFMEMORY
;
939 object
->IMFPMediaPlayer_iface
.lpVtbl
= &media_player_vtbl
;
940 object
->IPropertyStore_iface
.lpVtbl
= &media_player_propstore_vtbl
;
941 object
->resolver_callback
.lpVtbl
= &media_player_resolver_callback_vtbl
;
942 object
->refcount
= 1;
943 object
->callback
= callback
;
944 if (object
->callback
)
945 IMFPMediaPlayerCallback_AddRef(object
->callback
);
946 if (FAILED(hr
= CreatePropertyStore(&object
->propstore
)))
948 if (FAILED(hr
= MFCreateSourceResolver(&object
->resolver
)))
951 *player
= &object
->IMFPMediaPlayer_iface
;
957 IMFPMediaPlayer_Release(&object
->IMFPMediaPlayer_iface
);