mfplay: Implement CreateMediaItemFromObject().

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2021-04-16 15:36:08 +03:00 committed by Alexandre Julliard
parent 2b4715142a
commit 6b2627d59f
1 changed files with 111 additions and 9 deletions

View File

@ -61,6 +61,7 @@ struct media_item
IMFPresentationDescriptor *pd; IMFPresentationDescriptor *pd;
DWORD_PTR user_data; DWORD_PTR user_data;
WCHAR *url; WCHAR *url;
IUnknown *object;
}; };
struct media_player struct media_player
@ -340,6 +341,8 @@ static ULONG WINAPI media_item_Release(IMFPMediaItem *iface)
IMFMediaSource_Release(item->source); IMFMediaSource_Release(item->source);
if (item->pd) if (item->pd)
IMFPresentationDescriptor_Release(item->pd); IMFPresentationDescriptor_Release(item->pd);
if (item->object)
IUnknown_Release(item->object);
free(item->url); free(item->url);
free(item); free(item);
} }
@ -377,11 +380,19 @@ static HRESULT WINAPI media_item_GetURL(IMFPMediaItem *iface, LPWSTR *url)
return S_OK; 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) 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, 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); struct media_player *player = impl_from_IMFPMediaPlayer(iface);
HRESULT hr; 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); EnterCriticalSection(&player->cs);
if (player->state == MFP_MEDIAPLAYER_STATE_SHUTDOWN) if (player->state == MFP_MEDIAPLAYER_STATE_SHUTDOWN)
hr = MF_E_SHUTDOWN; hr = MF_E_SHUTDOWN;
else 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); LeaveCriticalSection(&player->cs);
return hr; 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, static HRESULT WINAPI media_player_CreateMediaItemFromObject(IMFPMediaPlayer *iface,
IUnknown *object, BOOL sync, DWORD_PTR user_data, IMFPMediaItem **item) 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) 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); 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); hr = media_item_set_source(item, object);
IUnknown_Release(object); IUnknown_Release(object);