[PATCH 2/3] mfplay: Handle shutdown state in media item methods.
Nikolay Sivov
nsivov at codeweavers.com
Mon Feb 14 05:49:12 CST 2022
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/mfplay/player.c | 214 ++++++++++++++++++++++++++--------
dlls/mfplay/tests/Makefile.in | 4 +-
dlls/mfplay/tests/mfplay.c | 147 ++++++++++++++++++++++-
dlls/mfplay/tests/resource.rc | 22 ++++
dlls/mfplay/tests/test.mp4 | Bin 0 -> 1554 bytes
5 files changed, 336 insertions(+), 51 deletions(-)
create mode 100644 dlls/mfplay/tests/resource.rc
create mode 100644 dlls/mfplay/tests/test.mp4
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c
index 31c8e094cd2..d8c13cc22a8 100644
--- a/dlls/mfplay/player.c
+++ b/dlls/mfplay/player.c
@@ -59,11 +59,13 @@ static inline const char *debugstr_normalized_rect(const MFVideoNormalizedRect *
return wine_dbg_sprintf("(%.8e,%.8e)-(%.8e,%.8e)", rect->left, rect->top, rect->right, rect->bottom);
}
+struct media_player;
+
struct media_item
{
IMFPMediaItem IMFPMediaItem_iface;
LONG refcount;
- IMFPMediaPlayer *player;
+ struct media_player *player;
IMFMediaSource *source;
IMFPresentationDescriptor *pd;
DWORD_PTR user_data;
@@ -308,6 +310,16 @@ static void media_player_set_state(struct media_player *player, MFP_MEDIAPLAYER_
}
}
+static HRESULT media_item_get_pd(const struct media_item *item, IMFPresentationDescriptor **pd)
+{
+ if (item->player->state == MFP_MEDIAPLAYER_STATE_SHUTDOWN)
+ return MF_E_SHUTDOWN;
+
+ *pd = item->pd;
+ IMFPresentationDescriptor_AddRef(*pd);
+ return S_OK;
+}
+
static HRESULT WINAPI media_item_QueryInterface(IMFPMediaItem *iface, REFIID riid, void **obj)
{
TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
@@ -345,7 +357,7 @@ static ULONG WINAPI media_item_Release(IMFPMediaItem *iface)
if (!refcount)
{
if (item->player)
- IMFPMediaPlayer_Release(item->player);
+ IMFPMediaPlayer_Release(&item->player->IMFPMediaPlayer_iface);
if (item->source)
IMFMediaSource_Release(item->source);
if (item->pd)
@@ -363,45 +375,70 @@ static HRESULT WINAPI media_item_GetMediaPlayer(IMFPMediaItem *iface,
IMFPMediaPlayer **player)
{
struct media_item *item = impl_from_IMFPMediaItem(iface);
+ HRESULT hr = S_OK;
TRACE("%p, %p.\n", iface, player);
- *player = item->player;
- IMFPMediaPlayer_AddRef(*player);
+ EnterCriticalSection(&item->player->cs);
+ if (item->player->state == MFP_MEDIAPLAYER_STATE_SHUTDOWN)
+ {
+ hr = MF_E_SHUTDOWN;
+ *player = NULL;
+ }
+ else
+ {
+ *player = &item->player->IMFPMediaPlayer_iface;
+ IMFPMediaPlayer_AddRef(*player);
+ }
+ LeaveCriticalSection(&item->player->cs);
- return S_OK;
+ return hr;
}
static HRESULT WINAPI media_item_GetURL(IMFPMediaItem *iface, LPWSTR *url)
{
struct media_item *item = impl_from_IMFPMediaItem(iface);
+ HRESULT hr = S_OK;
TRACE("%p, %p.\n", iface, url);
- if (!item->url)
- return MF_E_NOT_FOUND;
-
- if (!(*url = CoTaskMemAlloc((wcslen(item->url) + 1) * sizeof(*item->url))))
- return E_OUTOFMEMORY;
-
- wcscpy(*url, item->url);
+ EnterCriticalSection(&item->player->cs);
+ if (item->player->state == MFP_MEDIAPLAYER_STATE_SHUTDOWN)
+ hr = MF_E_SHUTDOWN;
+ else if (!item->url)
+ hr = MF_E_NOT_FOUND;
+ else
+ {
+ if (!(*url = CoTaskMemAlloc((wcslen(item->url) + 1) * sizeof(*item->url))))
+ hr = E_OUTOFMEMORY;
+ if (*url)
+ wcscpy(*url, item->url);
+ }
+ LeaveCriticalSection(&item->player->cs);
- return S_OK;
+ return hr;
}
static HRESULT WINAPI media_item_GetObject(IMFPMediaItem *iface, IUnknown **object)
{
struct media_item *item = impl_from_IMFPMediaItem(iface);
+ HRESULT hr = S_OK;
TRACE("%p, %p.\n", iface, object);
- if (!item->object)
- return MF_E_NOT_FOUND;
-
- *object = item->object;
- IUnknown_AddRef(*object);
+ EnterCriticalSection(&item->player->cs);
+ if (item->player->state == MFP_MEDIAPLAYER_STATE_SHUTDOWN)
+ hr = MF_E_SHUTDOWN;
+ else if (!item->object)
+ hr = MF_E_NOT_FOUND;
+ else
+ {
+ *object = item->object;
+ IUnknown_AddRef(*object);
+ }
+ LeaveCriticalSection(&item->player->cs);
- return S_OK;
+ return hr;
}
static HRESULT WINAPI media_item_GetUserData(IMFPMediaItem *iface, DWORD_PTR *user_data)
@@ -530,28 +567,38 @@ static HRESULT media_item_get_stream_type(IMFStreamDescriptor *sd, GUID *major)
static HRESULT media_item_has_stream(struct media_item *item, const GUID *major, BOOL *has_stream, BOOL *is_selected)
{
+ IMFPresentationDescriptor *pd;
IMFStreamDescriptor *sd;
unsigned int idx = 0;
BOOL selected;
+ HRESULT hr;
GUID guid;
- *has_stream = *is_selected = FALSE;
+ EnterCriticalSection(&item->player->cs);
- while (SUCCEEDED(IMFPresentationDescriptor_GetStreamDescriptorByIndex(item->pd, idx++, &selected, &sd)))
+ if (SUCCEEDED(hr = media_item_get_pd(item, &pd)))
{
- if (SUCCEEDED(media_item_get_stream_type(sd, &guid)) && IsEqualGUID(&guid, major))
+ *has_stream = *is_selected = FALSE;
+
+ while (SUCCEEDED(IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, idx++, &selected, &sd)))
{
- *has_stream = TRUE;
- *is_selected = selected;
- }
+ if (SUCCEEDED(media_item_get_stream_type(sd, &guid)) && IsEqualGUID(&guid, major))
+ {
+ *has_stream = TRUE;
+ *is_selected = selected;
+ }
- IMFStreamDescriptor_Release(sd);
+ IMFStreamDescriptor_Release(sd);
- if (*has_stream && *is_selected)
- break;
+ if (*has_stream && *is_selected)
+ break;
+ }
+ IMFPresentationDescriptor_Release(pd);
}
- return S_OK;
+ LeaveCriticalSection(&item->player->cs);
+
+ return hr;
}
static HRESULT WINAPI media_item_HasVideo(IMFPMediaItem *iface, BOOL *has_video, BOOL *selected)
@@ -575,42 +622,77 @@ static HRESULT WINAPI media_item_HasAudio(IMFPMediaItem *iface, BOOL *has_audio,
static HRESULT WINAPI media_item_IsProtected(IMFPMediaItem *iface, BOOL *protected)
{
struct media_item *item = impl_from_IMFPMediaItem(iface);
+ IMFPresentationDescriptor *pd;
+ HRESULT hr;
TRACE("%p, %p.\n", iface, protected);
- *protected = MFRequireProtectedEnvironment(item->pd) == S_OK;
+ EnterCriticalSection(&item->player->cs);
+ if (SUCCEEDED(hr = media_item_get_pd(item, &pd)))
+ {
+ *protected = MFRequireProtectedEnvironment(pd) == S_OK;
+ IMFPresentationDescriptor_Release(pd);
+ }
+ LeaveCriticalSection(&item->player->cs);
- return S_OK;
+ return hr;
}
static HRESULT WINAPI media_item_GetDuration(IMFPMediaItem *iface, REFGUID format, PROPVARIANT *value)
{
struct media_item *item = impl_from_IMFPMediaItem(iface);
+ IMFPresentationDescriptor *pd;
+ HRESULT hr;
TRACE("%p, %s, %p.\n", iface, debugstr_guid(format), value);
- return IMFPresentationDescriptor_GetItem(item->pd, &MF_PD_DURATION, value);
+ EnterCriticalSection(&item->player->cs);
+ if (SUCCEEDED(hr = media_item_get_pd(item, &pd)))
+ {
+ hr = IMFPresentationDescriptor_GetItem(pd, &MF_PD_DURATION, value);
+ IMFPresentationDescriptor_Release(pd);
+ }
+ LeaveCriticalSection(&item->player->cs);
+
+ return hr;
}
static HRESULT WINAPI media_item_GetNumberOfStreams(IMFPMediaItem *iface, DWORD *count)
{
struct media_item *item = impl_from_IMFPMediaItem(iface);
+ IMFPresentationDescriptor *pd;
+ HRESULT hr;
TRACE("%p, %p.\n", iface, count);
- return IMFPresentationDescriptor_GetStreamDescriptorCount(item->pd, count);
+ EnterCriticalSection(&item->player->cs);
+ if (SUCCEEDED(hr = media_item_get_pd(item, &pd)))
+ {
+ hr = IMFPresentationDescriptor_GetStreamDescriptorCount(pd, count);
+ IMFPresentationDescriptor_Release(pd);
+ }
+ LeaveCriticalSection(&item->player->cs);
+
+ return hr;
}
static HRESULT WINAPI media_item_GetStreamSelection(IMFPMediaItem *iface, DWORD index, BOOL *selected)
{
struct media_item *item = impl_from_IMFPMediaItem(iface);
+ IMFPresentationDescriptor *pd;
IMFStreamDescriptor *sd;
HRESULT hr;
TRACE("%p, %lu, %p.\n", iface, index, selected);
- if (SUCCEEDED(hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(item->pd, index, selected, &sd)))
- IMFStreamDescriptor_Release(sd);
+ EnterCriticalSection(&item->player->cs);
+ if (SUCCEEDED(hr = media_item_get_pd(item, &pd)))
+ {
+ if (SUCCEEDED(hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, index, selected, &sd)))
+ IMFStreamDescriptor_Release(sd);
+ IMFPresentationDescriptor_Release(pd);
+ }
+ LeaveCriticalSection(&item->player->cs);
return hr;
}
@@ -618,28 +700,45 @@ static HRESULT WINAPI media_item_GetStreamSelection(IMFPMediaItem *iface, DWORD
static HRESULT WINAPI media_item_SetStreamSelection(IMFPMediaItem *iface, DWORD index, BOOL select)
{
struct media_item *item = impl_from_IMFPMediaItem(iface);
+ IMFPresentationDescriptor *pd;
+ HRESULT hr;
TRACE("%p, %lu, %d.\n", iface, index, select);
- return select ? IMFPresentationDescriptor_SelectStream(item->pd, index) :
- IMFPresentationDescriptor_DeselectStream(item->pd, index);
+ EnterCriticalSection(&item->player->cs);
+ if (SUCCEEDED(hr = media_item_get_pd(item, &pd)))
+ {
+ hr = select ? IMFPresentationDescriptor_SelectStream(pd, index) :
+ IMFPresentationDescriptor_DeselectStream(pd, index);
+ IMFPresentationDescriptor_Release(pd);
+ }
+ LeaveCriticalSection(&item->player->cs);
+
+ return hr;
}
static HRESULT WINAPI media_item_GetStreamAttribute(IMFPMediaItem *iface, DWORD index, REFGUID key,
PROPVARIANT *value)
{
struct media_item *item = impl_from_IMFPMediaItem(iface);
+ IMFPresentationDescriptor *pd;
IMFStreamDescriptor *sd;
BOOL selected;
HRESULT hr;
TRACE("%p, %lu, %s, %p.\n", iface, index, debugstr_guid(key), value);
- if (SUCCEEDED(hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(item->pd, index, &selected, &sd)))
+ EnterCriticalSection(&item->player->cs);
+ if (SUCCEEDED(hr = media_item_get_pd(item, &pd)))
{
- hr = IMFStreamDescriptor_GetItem(sd, key, value);
- IMFStreamDescriptor_Release(sd);
+ if (SUCCEEDED(hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, index, &selected, &sd)))
+ {
+ hr = IMFStreamDescriptor_GetItem(sd, key, value);
+ IMFStreamDescriptor_Release(sd);
+ }
+ IMFPresentationDescriptor_Release(pd);
}
+ LeaveCriticalSection(&item->player->cs);
return hr;
}
@@ -648,10 +747,20 @@ static HRESULT WINAPI media_item_GetPresentationAttribute(IMFPMediaItem *iface,
PROPVARIANT *value)
{
struct media_item *item = impl_from_IMFPMediaItem(iface);
+ IMFPresentationDescriptor *pd;
+ HRESULT hr;
TRACE("%p, %s, %p.\n", iface, debugstr_guid(key), value);
- return IMFPresentationDescriptor_GetItem(item->pd, key, value);
+ EnterCriticalSection(&item->player->cs);
+ if (SUCCEEDED(hr = media_item_get_pd(item, &pd)))
+ {
+ hr = IMFPresentationDescriptor_GetItem(pd, key, value);
+ IMFPresentationDescriptor_Release(pd);
+ }
+ LeaveCriticalSection(&item->player->cs);
+
+ return hr;
}
static HRESULT WINAPI media_item_GetCharacteristics(IMFPMediaItem *iface, MFP_MEDIAITEM_CHARACTERISTICS *flags)
@@ -664,11 +773,18 @@ static HRESULT WINAPI media_item_GetCharacteristics(IMFPMediaItem *iface, MFP_ME
*flags = 0;
- if (SUCCEEDED(hr = IMFMediaSource_GetCharacteristics(item->source, &value)))
+ EnterCriticalSection(&item->player->cs);
+ if (item->player->state == MFP_MEDIAPLAYER_STATE_SHUTDOWN)
+ hr = MF_E_SHUTDOWN;
+ else
{
- *flags = value & (MFP_MEDIAITEM_IS_LIVE | MFP_MEDIAITEM_CAN_SEEK |
- MFP_MEDIAITEM_CAN_PAUSE | MFP_MEDIAITEM_HAS_SLOW_SEEK);
+ if (SUCCEEDED(hr = IMFMediaSource_GetCharacteristics(item->source, &value)))
+ {
+ *flags = value & (MFP_MEDIAITEM_IS_LIVE | MFP_MEDIAITEM_CAN_SEEK
+ | MFP_MEDIAITEM_CAN_PAUSE | MFP_MEDIAITEM_HAS_SLOW_SEEK);
+ }
}
+ LeaveCriticalSection(&item->player->cs);
return hr;
}
@@ -749,7 +865,7 @@ static struct media_item *unsafe_impl_from_IMFPMediaItem(IMFPMediaItem *iface)
return CONTAINING_RECORD(iface, struct media_item, IMFPMediaItem_iface);
}
-static HRESULT create_media_item(IMFPMediaPlayer *player, DWORD_PTR user_data, struct media_item **item)
+static HRESULT create_media_item(struct media_player *player, DWORD_PTR user_data, struct media_item **item)
{
struct media_item *object;
@@ -760,7 +876,7 @@ static HRESULT create_media_item(IMFPMediaPlayer *player, DWORD_PTR user_data, s
object->refcount = 1;
object->user_data = user_data;
object->player = player;
- IMFPMediaPlayer_AddRef(object->player);
+ IMFPMediaPlayer_AddRef(&object->player->IMFPMediaPlayer_iface);
*item = object;
@@ -1034,7 +1150,7 @@ static HRESULT media_player_create_item_from_url(struct media_player *player,
return MF_E_INVALIDREQUEST;
}
- if (FAILED(hr = create_media_item(&player->IMFPMediaPlayer_iface, user_data, &item)))
+ if (FAILED(hr = create_media_item(player, user_data, &item)))
return hr;
if (url && !(item->url = wcsdup(url)))
@@ -1105,7 +1221,7 @@ static HRESULT media_player_create_item_from_object(struct media_player *player,
*ret = NULL;
- if (FAILED(hr = create_media_item(&player->IMFPMediaPlayer_iface, user_data, &item)))
+ if (FAILED(hr = create_media_item(player, user_data, &item)))
return hr;
item->object = object;
@@ -1302,7 +1418,7 @@ static HRESULT WINAPI media_player_SetMediaItem(IMFPMediaPlayer *iface, IMFPMedi
return E_POINTER;
item = unsafe_impl_from_IMFPMediaItem(item_iface);
- if (item->player != iface)
+ if (item->player != player)
return E_INVALIDARG;
if (FAILED(hr = media_item_create_topology(player, item, &topology)))
diff --git a/dlls/mfplay/tests/Makefile.in b/dlls/mfplay/tests/Makefile.in
index 4eabb5ae0ab..e790fa3e2ad 100644
--- a/dlls/mfplay/tests/Makefile.in
+++ b/dlls/mfplay/tests/Makefile.in
@@ -1,5 +1,7 @@
TESTDLL = mfplay.dll
-IMPORTS = mfplay user32 uuid mfuuid
+IMPORTS = mfplay user32 uuid mfuuid mfplat
C_SRCS = \
mfplay.c
+
+RC_SRCS = resource.rc
diff --git a/dlls/mfplay/tests/mfplay.c b/dlls/mfplay/tests/mfplay.c
index 44526801c22..c58f34e8b31 100644
--- a/dlls/mfplay/tests/mfplay.c
+++ b/dlls/mfplay/tests/mfplay.c
@@ -42,6 +42,34 @@ static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOO
IUnknown_Release(unk);
}
+static WCHAR *load_resource(const WCHAR *name)
+{
+ static WCHAR pathW[MAX_PATH];
+ DWORD written;
+ HANDLE file;
+ HRSRC res;
+ void *ptr;
+
+ GetTempPathW(ARRAY_SIZE(pathW), pathW);
+ lstrcatW(pathW, name);
+
+ file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0,
+ NULL, CREATE_ALWAYS, 0, 0);
+ ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %ld.\n",
+ wine_dbgstr_w(pathW), GetLastError());
+
+ res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA);
+ ok(res != 0, "couldn't find resource\n");
+ ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res));
+ WriteFile(file, ptr, SizeofResource(GetModuleHandleA(NULL), res),
+ &written, NULL);
+ ok(written == SizeofResource(GetModuleHandleA(NULL), res),
+ "couldn't write resource\n" );
+ CloseHandle(file);
+
+ return pathW;
+}
+
static HRESULT WINAPI test_callback_QueryInterface(IMFPMediaPlayerCallback *iface, REFIID riid, void **obj)
{
if (IsEqualIID(riid, &IID_IMFPMediaPlayerCallback) ||
@@ -243,8 +271,15 @@ static void test_shutdown(void)
static void test_media_item(void)
{
- IMFPMediaPlayer *player;
+ IMFPMediaPlayer *player, *player2;
+ WCHAR *filename, *url;
IMFPMediaItem *item;
+ DWORD_PTR user_data;
+ PROPVARIANT propvar;
+ unsigned int flags;
+ BOOL ret, selected;
+ IUnknown *object;
+ DWORD count;
HRESULT hr;
hr = MFPCreateMediaPlayer(NULL, FALSE, 0, NULL, NULL, &player);
@@ -263,6 +298,116 @@ static void test_media_item(void)
hr = IMFPMediaPlayer_CreateMediaItemFromURL(player, L"url", TRUE, 0, NULL);
ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
+ filename = load_resource(L"test.mp4");
+
+ hr = IMFPMediaPlayer_CreateMediaItemFromURL(player, filename, TRUE, 123, &item);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+
+ hr = IMFPMediaItem_GetMediaPlayer(item, &player2);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ ok(player2 == player, "Unexpected player pointer.\n");
+ IMFPMediaPlayer_Release(player2);
+
+ hr = IMFPMediaItem_GetURL(item, &url);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+
+ hr = IMFPMediaItem_GetObject(item, &object);
+ ok(hr == MF_E_NOT_FOUND, "Unexpected hr %#lx.\n", hr);
+
+ hr = IMFPMediaItem_GetUserData(item, &user_data);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ ok(user_data == 123, "Unexpected user data %#Ix.\n", user_data);
+
+ hr = IMFPMediaItem_SetUserData(item, 124);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+
+ hr = IMFPMediaItem_HasVideo(item, &ret, &selected);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ ok(ret && selected, "Unexpected flags.\n");
+
+ hr = IMFPMediaItem_HasAudio(item, &ret, &selected);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+
+ hr = IMFPMediaItem_IsProtected(item, &ret);
+ todo_wine
+ ok(hr == S_FALSE, "Unexpected hr %#lx.\n", hr);
+
+ hr = IMFPMediaItem_GetDuration(item, &MFP_POSITIONTYPE_100NS, &propvar);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+
+ hr = IMFPMediaItem_GetNumberOfStreams(item, &count);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+
+ hr = IMFPMediaItem_GetStreamSelection(item, 0, &ret);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+
+ hr = IMFPMediaItem_SetStreamSelection(item, 0, FALSE);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+
+ hr = IMFPMediaItem_GetStreamAttribute(item, 0, &MF_SD_LANGUAGE, &propvar);
+ ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr);
+
+ hr = IMFPMediaItem_GetPresentationAttribute(item, &MF_PD_DURATION, &propvar);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+
+ hr = IMFPMediaItem_GetCharacteristics(item, &flags);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+
+ /* Player shutdown affects created items. */
+ hr = IMFPMediaPlayer_Shutdown(player);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+
+ hr = IMFPMediaItem_GetMediaPlayer(item, &player2);
+ ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
+ ok(!player2, "Unexpected pointer %p.\n", player2);
+
+ hr = IMFPMediaItem_GetURL(item, &url);
+ ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
+
+ hr = IMFPMediaItem_GetObject(item, &object);
+ ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
+
+ hr = IMFPMediaItem_GetUserData(item, &user_data);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ ok(user_data == 124, "Unexpected user data %#Ix.\n", user_data);
+
+ hr = IMFPMediaItem_SetUserData(item, 125);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+
+ hr = IMFPMediaItem_HasVideo(item, &ret, &selected);
+ ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
+
+ hr = IMFPMediaItem_HasAudio(item, &ret, &selected);
+ ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
+
+ hr = IMFPMediaItem_IsProtected(item, &ret);
+ ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
+
+ hr = IMFPMediaItem_GetDuration(item, &MFP_POSITIONTYPE_100NS, &propvar);
+ ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
+
+ hr = IMFPMediaItem_GetNumberOfStreams(item, &count);
+ ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
+
+ hr = IMFPMediaItem_GetStreamSelection(item, 0, &ret);
+ ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
+
+ hr = IMFPMediaItem_SetStreamSelection(item, 0, FALSE);
+ ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
+
+ hr = IMFPMediaItem_GetStreamAttribute(item, 0, &MF_SD_LANGUAGE, &propvar);
+ ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
+
+ hr = IMFPMediaItem_GetPresentationAttribute(item, &MF_PD_DURATION, &propvar);
+ ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
+
+ hr = IMFPMediaItem_GetCharacteristics(item, &flags);
+ ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#lx.\n", hr);
+
+ IMFPMediaItem_Release(item);
+
+ DeleteFileW(filename);
+
IMFPMediaPlayer_Release(player);
}
diff --git a/dlls/mfplay/tests/resource.rc b/dlls/mfplay/tests/resource.rc
new file mode 100644
index 00000000000..38c4a5f9e01
--- /dev/null
+++ b/dlls/mfplay/tests/resource.rc
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2018 Sven Baars
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "windef.h"
+
+/* @makedep: test.mp4 */
+test.mp4 RCDATA test.mp4
diff --git a/dlls/mfplay/tests/test.mp4 b/dlls/mfplay/tests/test.mp4
new file mode 100644
index 0000000000000000000000000000000000000000..a5bbca6bbf7692eab047050b79b8ccc83516e6b4
GIT binary patch
literal 1554
zcmZuxeN0nV6u<3bttg}g3M<<3v4A5C7=;cYskS&=aH+Gw(TQ=|2k#+BpKbac6$q26
zgvfMZE^O--6L1NclR1flh8QLw4%rM5#eGC{R2Jv(j|s9(8MANazOwnmo#gk<x#yhw
zyZ4 at R-$e*%%DGx+CF@`ik|L}DS&UP!LkKM^chNNX_cIj9Atd<{DdnJiN*lZEK&*TH
zLUnilE|&Pi#`t<(V2JeCh0xUFbE~$JpP!3QD)e^to at B05Kdu~jt~KuYz}1=h$wy;^
z-(P&iYuL#r*6qMlmYD;w&8gboiuVmim)E`@VY(w}d_`I2ihOP3>WzsJPV$oN<)LWX
zeE-6+iWMz`xA<B45szMa^nqwQ5w>wzrc-v;{3ns3&Hgygab at co_v%sWh^~kxZdgv1
zG$e27=y&X0FwfM)&vJ1wQfF>hX5`>p!|hca@<xwAt#6-gnD>;lG>BPmWrt3nUp`73
z+Yr|+TbnzS=UsV1v;C6gviW|rw)-!S-=bHn;0v1+QGDC}Ia|1D&?ob%jF`h$Wc#Ew
zV;vf3`obS*$vM<kEDwCQ`|#nw>4L6xr#4wnKY06wGT*}wdIn7LW=}zVn#?n%4mVMz
zS*QG<-xMcs%$)a1n<6jX{=IjfF~joa!xMeyYRwY|Cr0Vm>*3w%uu#*`=0;_WapAn$
zU<`El at AbuA79AjpWMkq|c1;#tZJ#~+J(2cx>Nm%BvdmP*5AP|wGW~$TESZLVhn6a1
ztO^C+GL%><v}DW7eXsQJ-HUG|I!ZcwqEv0#Ya at m<t5KG7N5rlo$2IYtr*eGsbj8h0
z?c at jJ8?GH6PW~!_$shUIcJraKf^47ff8>qKKRQs;^7r5rKP{`hCoZsRD*LTIOV>}^
zv}Z#0Dsy%(f4!(s5zT+wRX-W1@{bU&DxT$gcYNB95Wz4GhZ`=WopD!CphZIb3Y&Tt
zN#HB;J~@EE6G4Pb;@qcgDO~ywITu+4q3v9iuqGi&TV#WEm&%fL{&(FFn1q2)5>0U|
zXbo*=;Rh207#4X2E~$c{DoKbWFx1ksXMtOViZ2NB(km#tOR(VMuB70{eJoZOI||7?
zl%2*olCw<Zo^mi$Zbl##Z##(!#x#_R#yMDUJgnMfPYBwQI+iQ7gFVc0?7t1cIX-wf
zaHFt at IfI@MICdeJ7+9Xp2>Ks?)jSUa8_iO<Oo;G!Jey%!2<ZHT2<$>SD4dRa20SkU
zV;68rdYYqx<dOt*;hjTh6eXe7GH{(SlkT#Yax=1Y8M;ip4CY9n)kw{9LK`q0-qUjY
z7J{U}>4bH`mH}`KUjy7ccnDD_0CJHA at _=3toU_OwXamIR7Gqf9{35_wfE7@%h&<3n
zKs;bQARC}!xiSZ6ESNJ5P+CoKB<O7nEod-NqPX>NU0kHoiM#Wkq*n&-SMq0^0~2cD
TJ;x-N6hTeOp(eUDP!ruh^$B~#
literal 0
HcmV?d00001
--
2.34.1
More information about the wine-devel
mailing list