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