mfplay: Implement IsProtected().
[wine/zf.git] / dlls / mfplay / player.c
blob854698774a65cf03dfcae6a85e27fe510cff80ae
1 /*
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
19 #define COBJMACROS
21 #include <stdarg.h>
23 #include "windef.h"
24 #include "winbase.h"
25 #include "mfapi.h"
26 #include "mfplay.h"
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)
44 MFShutdown();
47 struct media_item
49 IMFPMediaItem IMFPMediaItem_iface;
50 LONG refcount;
51 IMFPMediaPlayer *player;
52 IMFMediaSource *source;
53 IMFPresentationDescriptor *pd;
54 DWORD_PTR user_data;
57 struct media_player
59 IMFPMediaPlayer IMFPMediaPlayer_iface;
60 IPropertyStore IPropertyStore_iface;
61 IMFAsyncCallback resolver_callback;
62 LONG refcount;
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))
95 *obj = iface;
96 IMFPMediaItem_AddRef(iface);
97 return S_OK;
100 WARN("Unsupported interface %s.\n", debugstr_guid(riid));
101 *obj = NULL;
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);
112 return 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);
122 if (!refcount)
124 if (item->player)
125 IMFPMediaPlayer_Release(item->player);
126 if (item->source)
127 IMFMediaSource_Release(item->source);
128 if (item->pd)
129 IMFPresentationDescriptor_Release(item->pd);
130 heap_free(item);
133 return refcount;
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);
146 return S_OK;
149 static HRESULT WINAPI media_item_GetURL(IMFPMediaItem *iface, LPWSTR *url)
151 FIXME("%p, %p.\n", iface, url);
153 return E_NOTIMPL;
156 static HRESULT WINAPI media_item_GetObject(IMFPMediaItem *iface, IUnknown **obj)
158 FIXME("%p, %p.\n", iface, obj);
160 return E_NOTIMPL;
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;
171 return S_OK;
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;
182 return S_OK;
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);
190 return E_NOTIMPL;
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);
199 return E_NOTIMPL;
202 static HRESULT WINAPI media_item_HasVideo(IMFPMediaItem *iface, BOOL *has_video, BOOL *selected)
204 FIXME("%p, %p, %p.\n", iface, has_video, selected);
206 return E_NOTIMPL;
209 static HRESULT WINAPI media_item_HasAudio(IMFPMediaItem *iface, BOOL *has_audio, BOOL *selected)
211 FIXME("%p, %p, %p.\n", iface, has_audio, selected);
213 return E_NOTIMPL;
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;
224 return 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);
231 return E_NOTIMPL;
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;
247 HRESULT hr;
249 TRACE("%p, %u, %p.\n", iface, index, selected);
251 if (SUCCEEDED(hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(item->pd, index, selected, &sd)))
252 IMFStreamDescriptor_Release(sd);
254 return hr;
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,
268 PROPVARIANT *value)
270 struct media_item *item = impl_from_IMFPMediaItem(iface);
271 IMFStreamDescriptor *sd;
272 BOOL selected;
273 HRESULT hr;
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);
283 return hr;
286 static HRESULT WINAPI media_item_GetPresentationAttribute(IMFPMediaItem *iface, REFGUID key,
287 PROPVARIANT *value)
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);
300 return E_NOTIMPL;
303 static HRESULT WINAPI media_item_SetStreamSink(IMFPMediaItem *iface, DWORD index, IUnknown *sink)
305 FIXME("%p, %u, %p.\n", iface, index, sink);
307 return E_NOTIMPL;
310 static HRESULT WINAPI media_item_GetMetadata(IMFPMediaItem *iface, IPropertyStore **metadata)
312 FIXME("%p, %p.\n", iface, metadata);
314 return E_NOTIMPL;
317 static const IMFPMediaItemVtbl media_item_vtbl =
319 media_item_QueryInterface,
320 media_item_AddRef,
321 media_item_Release,
322 media_item_GetMediaPlayer,
323 media_item_GetURL,
324 media_item_GetObject,
325 media_item_GetUserData,
326 media_item_SetUserData,
327 media_item_GetStartStopPosition,
328 media_item_SetStartStopPosition,
329 media_item_HasVideo,
330 media_item_HasAudio,
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);
356 *item = object;
358 return S_OK;
361 static HRESULT media_item_set_source(struct media_item *item, IUnknown *object)
363 IMFPresentationDescriptor *pd;
364 IMFMediaSource *source;
365 HRESULT hr;
367 if (FAILED(hr = IUnknown_QueryInterface(object, &IID_IMFMediaSource, (void **)&source)))
368 return hr;
370 if (FAILED(hr = IMFMediaSource_CreatePresentationDescriptor(source, &pd)))
372 WARN("Failed to get presentation descriptor, hr %#x.\n", hr);
373 IMFMediaSource_Release(source);
374 return hr;
377 item->source = source;
378 item->pd = pd;
380 return hr;
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;
398 else
400 WARN("Unsupported interface %s.\n", debugstr_guid(riid));
401 *obj = NULL;
403 return E_NOINTERFACE;
406 IUnknown_AddRef((IUnknown *)*obj);
407 return S_OK;
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);
417 return 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);
427 if (!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);
435 heap_free(player);
437 platform_shutdown();
440 return refcount;
443 static HRESULT WINAPI media_player_Play(IMFPMediaPlayer *iface)
445 FIXME("%p.\n", iface);
447 return E_NOTIMPL;
450 static HRESULT WINAPI media_player_Pause(IMFPMediaPlayer *iface)
452 FIXME("%p.\n", iface);
454 return E_NOTIMPL;
457 static HRESULT WINAPI media_player_Stop(IMFPMediaPlayer *iface)
459 FIXME("%p.\n", iface);
461 return E_NOTIMPL;
464 static HRESULT WINAPI media_player_FrameStep(IMFPMediaPlayer *iface)
466 FIXME("%p.\n", iface);
468 return E_NOTIMPL;
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);
475 return E_NOTIMPL;
478 static HRESULT WINAPI media_player_GetPosition(IMFPMediaPlayer *iface, REFGUID postype, PROPVARIANT *position)
480 FIXME("%p, %s, %p.\n", iface, debugstr_guid(postype), position);
482 return E_NOTIMPL;
485 static HRESULT WINAPI media_player_GetDuration(IMFPMediaPlayer *iface, REFGUID postype, PROPVARIANT *position)
487 FIXME("%p, %s, %p.\n", iface, debugstr_guid(postype), position);
489 return E_NOTIMPL;
492 static HRESULT WINAPI media_player_SetRate(IMFPMediaPlayer *iface, float rate)
494 FIXME("%p, %f.\n", iface, rate);
496 return E_NOTIMPL;
499 static HRESULT WINAPI media_player_GetRate(IMFPMediaPlayer *iface, float *rate)
501 FIXME("%p, %p.\n", iface, rate);
503 return E_NOTIMPL;
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);
510 return E_NOTIMPL;
513 static HRESULT WINAPI media_player_GetState(IMFPMediaPlayer *iface, MFP_MEDIAPLAYER_STATE *state)
515 FIXME("%p, %p.\n", iface, state);
517 return E_NOTIMPL;
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;
526 IUnknown *object;
527 HRESULT hr;
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)))
532 return hr;
534 if (sync)
536 *ret = NULL;
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);
545 if (SUCCEEDED(hr))
546 *ret = &item->IMFPMediaItem_iface;
548 return hr;
550 else
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);
558 return hr;
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);
566 return E_NOTIMPL;
569 static HRESULT WINAPI media_player_SetMediaItem(IMFPMediaPlayer *iface, IMFPMediaItem *item)
571 FIXME("%p, %p.\n", iface, item);
573 return E_NOTIMPL;
576 static HRESULT WINAPI media_player_ClearMediaItem(IMFPMediaPlayer *iface)
578 FIXME("%p.\n", iface);
580 return E_NOTIMPL;
583 static HRESULT WINAPI media_player_GetMediaItem(IMFPMediaPlayer *iface, IMFPMediaItem **item)
585 FIXME("%p, %p.\n", iface, item);
587 return E_NOTIMPL;
590 static HRESULT WINAPI media_player_GetVolume(IMFPMediaPlayer *iface, float *volume)
592 FIXME("%p, %p.\n", iface, volume);
594 return E_NOTIMPL;
597 static HRESULT WINAPI media_player_SetVolume(IMFPMediaPlayer *iface, float volume)
599 FIXME("%p, %.8e.\n", iface, volume);
601 return E_NOTIMPL;
604 static HRESULT WINAPI media_player_GetBalance(IMFPMediaPlayer *iface, float *balance)
606 FIXME("%p, %p.\n", iface, balance);
608 return E_NOTIMPL;
611 static HRESULT WINAPI media_player_SetBalance(IMFPMediaPlayer *iface, float balance)
613 FIXME("%p, %.8e.\n", iface, balance);
615 return E_NOTIMPL;
618 static HRESULT WINAPI media_player_GetMute(IMFPMediaPlayer *iface, BOOL *mute)
620 FIXME("%p, %p.\n", iface, mute);
622 return E_NOTIMPL;
625 static HRESULT WINAPI media_player_SetMute(IMFPMediaPlayer *iface, BOOL mute)
627 FIXME("%p, %d.\n", iface, mute);
629 return E_NOTIMPL;
632 static HRESULT WINAPI media_player_GetNativeVideoSize(IMFPMediaPlayer *iface,
633 SIZE *video, SIZE *arvideo)
635 FIXME("%p, %p, %p.\n", iface, video, arvideo);
637 return E_NOTIMPL;
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);
645 return E_NOTIMPL;
648 static HRESULT WINAPI media_player_SetVideoSourceRect(IMFPMediaPlayer *iface,
649 MFVideoNormalizedRect const *rect)
651 FIXME("%p, %p.\n", iface, rect);
653 return E_NOTIMPL;
656 static HRESULT WINAPI media_player_GetVideoSourceRect(IMFPMediaPlayer *iface,
657 MFVideoNormalizedRect *rect)
659 FIXME("%p, %p.\n", iface, rect);
661 return E_NOTIMPL;
664 static HRESULT WINAPI media_player_SetAspectRatioMode(IMFPMediaPlayer *iface, DWORD mode)
666 FIXME("%p, %u.\n", iface, mode);
668 return E_NOTIMPL;
671 static HRESULT WINAPI media_player_GetAspectRatioMode(IMFPMediaPlayer *iface,
672 DWORD *mode)
674 FIXME("%p, %p.\n", iface, mode);
676 return E_NOTIMPL;
679 static HRESULT WINAPI media_player_GetVideoWindow(IMFPMediaPlayer *iface, HWND *hwnd)
681 FIXME("%p, %p.\n", iface, hwnd);
683 return E_NOTIMPL;
686 static HRESULT WINAPI media_player_UpdateVideo(IMFPMediaPlayer *iface)
688 FIXME("%p.\n", iface);
690 return E_NOTIMPL;
693 static HRESULT WINAPI media_player_SetBorderColor(IMFPMediaPlayer *iface, COLORREF color)
695 FIXME("%p, %#x.\n", iface, color);
697 return E_NOTIMPL;
700 static HRESULT WINAPI media_player_GetBorderColor(IMFPMediaPlayer *iface, COLORREF *color)
702 FIXME("%p, %p.\n", iface, color);
704 return E_NOTIMPL;
707 static HRESULT WINAPI media_player_InsertEffect(IMFPMediaPlayer *iface, IUnknown *effect,
708 BOOL optional)
710 FIXME("%p, %p, %d.\n", iface, effect, optional);
712 return E_NOTIMPL;
715 static HRESULT WINAPI media_player_RemoveEffect(IMFPMediaPlayer *iface, IUnknown *effect)
717 FIXME("%p, %p.\n", iface, effect);
719 return E_NOTIMPL;
722 static HRESULT WINAPI media_player_RemoveAllEffects(IMFPMediaPlayer *iface)
724 FIXME("%p.\n", iface);
726 return E_NOTIMPL;
729 static HRESULT WINAPI media_player_Shutdown(IMFPMediaPlayer *iface)
731 FIXME("%p.\n", iface);
733 return E_NOTIMPL;
736 static const IMFPMediaPlayerVtbl media_player_vtbl =
738 media_player_QueryInterface,
739 media_player_AddRef,
740 media_player_Release,
741 media_player_Play,
742 media_player_Pause,
743 media_player_Stop,
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))
861 *obj = iface;
862 IMFAsyncCallback_AddRef(iface);
863 return S_OK;
866 *obj = NULL;
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,
883 DWORD *queue)
885 return E_NOTIMPL;
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;
894 HRESULT hr;
896 if (FAILED(IMFAsyncResult_GetState(result, &state)))
897 return S_OK;
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);
907 if (FAILED(hr))
908 WARN("Failed to set media source, hr %#x.\n", hr);
910 /* FIXME: callback notification */
912 IUnknown_Release(state);
914 return S_OK;
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;
930 HRESULT hr;
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;
937 platform_startup();
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)))
947 goto failed;
948 if (FAILED(hr = MFCreateSourceResolver(&object->resolver)))
949 goto failed;
951 *player = &object->IMFPMediaPlayer_iface;
953 return S_OK;
955 failed:
957 IMFPMediaPlayer_Release(&object->IMFPMediaPlayer_iface);
959 return hr;