mfplay: Implement CreateMediaItemFromObject().
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
2b4715142a
commit
6b2627d59f
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue