Nikolay Sivov : mfplay: Implement CreateMediaItemFromObject().
Alexandre Julliard
julliard at winehq.org
Fri Apr 16 15:56:22 CDT 2021
Module: wine
Branch: master
Commit: 6b2627d59fcab7d5c6ff8ee90157f9f1da034126
URL: https://source.winehq.org/git/wine.git/?a=commit;h=6b2627d59fcab7d5c6ff8ee90157f9f1da034126
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Fri Apr 16 15:36:08 2021 +0300
mfplay: Implement CreateMediaItemFromObject().
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/mfplay/player.c | 120 +++++++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 111 insertions(+), 9 deletions(-)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c
index e57db8e107d..d6ed6ef5c39 100644
--- a/dlls/mfplay/player.c
+++ b/dlls/mfplay/player.c
@@ -61,6 +61,7 @@ struct media_item
IMFPresentationDescriptor *pd;
DWORD_PTR user_data;
WCHAR *url;
+ IUnknown *object;
};
struct media_player
@@ -340,6 +341,8 @@ static ULONG WINAPI media_item_Release(IMFPMediaItem *iface)
IMFMediaSource_Release(item->source);
if (item->pd)
IMFPresentationDescriptor_Release(item->pd);
+ if (item->object)
+ IUnknown_Release(item->object);
free(item->url);
free(item);
}
@@ -377,11 +380,19 @@ static HRESULT WINAPI media_item_GetURL(IMFPMediaItem *iface, LPWSTR *url)
return S_OK;
}
-static HRESULT WINAPI media_item_GetObject(IMFPMediaItem *iface, IUnknown **obj)
+static HRESULT WINAPI media_item_GetObject(IMFPMediaItem *iface, IUnknown **object)
{
- FIXME("%p, %p.\n", iface, obj);
+ struct media_item *item = impl_from_IMFPMediaItem(iface);
- return E_NOTIMPL;
+ TRACE("%p, %p.\n", iface, object);
+
+ if (!item->object)
+ return MF_E_NOT_FOUND;
+
+ *object = item->object;
+ IUnknown_AddRef(*object);
+
+ return S_OK;
}
static HRESULT WINAPI media_item_GetUserData(IMFPMediaItem *iface, DWORD_PTR *user_data)
@@ -856,29 +867,112 @@ static HRESULT media_player_create_item_from_url(struct media_player *player,
}
static HRESULT WINAPI media_player_CreateMediaItemFromURL(IMFPMediaPlayer *iface,
- const WCHAR *url, BOOL sync, DWORD_PTR user_data, IMFPMediaItem **ret)
+ const WCHAR *url, BOOL sync, DWORD_PTR user_data, IMFPMediaItem **item)
{
struct media_player *player = impl_from_IMFPMediaPlayer(iface);
HRESULT hr;
- TRACE("%p, %s, %d, %lx, %p.\n", iface, debugstr_w(url), sync, user_data, ret);
+ TRACE("%p, %s, %d, %lx, %p.\n", iface, debugstr_w(url), sync, user_data, item);
EnterCriticalSection(&player->cs);
if (player->state == MFP_MEDIAPLAYER_STATE_SHUTDOWN)
hr = MF_E_SHUTDOWN;
else
- hr = media_player_create_item_from_url(player, url, sync, user_data, ret);
+ hr = media_player_create_item_from_url(player, url, sync, user_data, item);
LeaveCriticalSection(&player->cs);
return hr;
}
+static HRESULT media_player_create_item_from_object(struct media_player *player,
+ IUnknown *object, BOOL sync, DWORD_PTR user_data, IMFPMediaItem **ret)
+{
+ struct media_item *item;
+ MF_OBJECT_TYPE obj_type;
+ HRESULT hr;
+ IMFByteStream *stream = NULL;
+ IMFMediaSource *source = NULL;
+
+ *ret = NULL;
+
+ if (FAILED(hr = create_media_item(&player->IMFPMediaPlayer_iface, user_data, &item)))
+ return hr;
+
+ item->object = object;
+ IUnknown_AddRef(item->object);
+
+ if (FAILED(IUnknown_QueryInterface(object, &IID_IMFMediaSource, (void **)&source)))
+ IUnknown_QueryInterface(object, &IID_IMFByteStream, (void **)&stream);
+
+ if (!source && !stream)
+ {
+ WARN("Unsupported object type.\n");
+ IMFPMediaItem_Release(&item->IMFPMediaItem_iface);
+ return E_UNEXPECTED;
+ }
+
+ if (sync)
+ {
+ if (stream)
+ hr = IMFSourceResolver_CreateObjectFromByteStream(player->resolver, stream, NULL,
+ MF_RESOLUTION_MEDIASOURCE, player->propstore, &obj_type, &object);
+ else
+ IUnknown_AddRef(object);
+
+ if (SUCCEEDED(hr))
+ hr = media_item_set_source(item, object);
+
+ IUnknown_Release(object);
+
+ if (SUCCEEDED(hr))
+ {
+ *ret = &item->IMFPMediaItem_iface;
+ IMFPMediaItem_AddRef(*ret);
+ }
+
+ IMFPMediaItem_Release(&item->IMFPMediaItem_iface);
+ }
+ else
+ {
+ if (stream)
+ {
+ hr = IMFSourceResolver_BeginCreateObjectFromByteStream(player->resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE,
+ player->propstore, NULL, &player->resolver_callback, (IUnknown *)&item->IMFPMediaItem_iface);
+ }
+ else
+ {
+ /* Resolver callback will check again if item's object is a source. */
+ hr = MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_MULTITHREADED, &player->resolver_callback,
+ (IUnknown *)&item->IMFPMediaItem_iface);
+ }
+
+ IMFPMediaItem_Release(&item->IMFPMediaItem_iface);
+ }
+
+ if (source)
+ IMFMediaSource_Release(source);
+ if (stream)
+ IMFByteStream_Release(stream);
+
+ return hr;
+}
+
static HRESULT WINAPI media_player_CreateMediaItemFromObject(IMFPMediaPlayer *iface,
IUnknown *object, BOOL sync, DWORD_PTR user_data, IMFPMediaItem **item)
{
- FIXME("%p, %p, %d, %lx, %p.\n", iface, object, sync, user_data, item);
+ struct media_player *player = impl_from_IMFPMediaPlayer(iface);
+ HRESULT hr;
- return E_NOTIMPL;
+ TRACE("%p, %p, %d, %lx, %p.\n", iface, object, sync, user_data, item);
+
+ EnterCriticalSection(&player->cs);
+ if (player->state == MFP_MEDIAPLAYER_STATE_SHUTDOWN)
+ hr = MF_E_SHUTDOWN;
+ else
+ hr = media_player_create_item_from_object(player, object, sync, user_data, item);
+ LeaveCriticalSection(&player->cs);
+
+ return hr;
}
static HRESULT media_item_get_stream_type(IMFStreamDescriptor *sd, GUID *major)
@@ -1344,7 +1438,15 @@ static HRESULT WINAPI media_player_resolver_callback_Invoke(IMFAsyncCallback *if
item = impl_from_IMFPMediaItem((IMFPMediaItem *)state);
- if (SUCCEEDED(hr = IMFSourceResolver_EndCreateObjectFromURL(player->resolver, result, &obj_type, &object)))
+ if (item->object)
+ {
+ if (FAILED(hr = IUnknown_QueryInterface(item->object, &IID_IMFMediaSource, (void **)&object)))
+ hr = IMFSourceResolver_EndCreateObjectFromByteStream(player->resolver, result, &obj_type, &object);
+ }
+ else
+ hr = IMFSourceResolver_EndCreateObjectFromURL(player->resolver, result, &obj_type, &object);
+
+ if (SUCCEEDED(hr))
{
hr = media_item_set_source(item, object);
IUnknown_Release(object);
More information about the wine-cvs
mailing list