Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/player.c | 75 +++++++++++++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 22 deletions(-)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index 51f3f67f5b1..87ddf613288 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -1015,13 +1015,38 @@ static HRESULT media_item_get_stream_type(IMFStreamDescriptor *sd, GUID *major) return hr; }
+static HRESULT media_item_create_source_node(struct media_item *item, IMFStreamDescriptor *sd, + IMFTopologyNode **node) +{ + HRESULT hr; + + if (SUCCEEDED(hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, node))) + { + IMFTopologyNode_SetUnknown(*node, &MF_TOPONODE_SOURCE, (IUnknown *)item->source); + IMFTopologyNode_SetUnknown(*node, &MF_TOPONODE_PRESENTATION_DESCRIPTOR, (IUnknown *)item->pd); + IMFTopologyNode_SetUnknown(*node, &MF_TOPONODE_STREAM_DESCRIPTOR, (IUnknown *)sd); + } + + return hr; +} + +static HRESULT media_item_create_sink_node(IUnknown *sink, IMFTopologyNode **node) +{ + HRESULT hr; + + if (SUCCEEDED(hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, node))) + IMFTopologyNode_SetObject(*node, sink); + + return hr; +} + static HRESULT media_item_create_topology(struct media_player *player, struct media_item *item, IMFTopology **out) { IMFTopologyNode *src_node, *sink_node; - IMFActivate *sar_activate; IMFStreamDescriptor *sd; IMFTopology *topology; unsigned int idx; + IUnknown *sink; BOOL selected; HRESULT hr; GUID major; @@ -1029,48 +1054,54 @@ static HRESULT media_item_create_topology(struct media_player *player, struct me if (FAILED(hr = MFCreateTopology(&topology))) return hr;
- /* FIXME: handle user sinks */ - /* Use first stream if none selected. */ if (player->output_window) { FIXME("Video streams are not handled.\n"); }
- /* Set up audio branches for all selected streams. */ + /* Set up branches for all selected streams. */
idx = 0; while (SUCCEEDED(IMFPresentationDescriptor_GetStreamDescriptorByIndex(item->pd, idx++, &selected, &sd))) { - if (selected && SUCCEEDED(media_item_get_stream_type(sd, &major)) && IsEqualGUID(&major, &MFMediaType_Audio)) + if (!selected) { - if (SUCCEEDED(hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &src_node))) - { - IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_SOURCE, (IUnknown *)item->source); - IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_PRESENTATION_DESCRIPTOR, (IUnknown *)item->pd); - IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_STREAM_DESCRIPTOR, (IUnknown *)sd); + IMFStreamDescriptor_Release(sd); + continue; + }
- IMFTopology_AddNode(topology, src_node); - } + sink = NULL;
- if (SUCCEEDED(hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &sink_node))) - { - if (SUCCEEDED(MFCreateAudioRendererActivate(&sar_activate))) - { - IMFTopologyNode_SetObject(sink_node, (IUnknown *)sar_activate); - IMFActivate_Release(sar_activate); - } + if (SUCCEEDED(IMFStreamDescriptor_GetUnknown(sd, &_MF_CUSTOM_SINK, &IID_IUnknown, (void **)&sink))) + { + /* User sink is attached as-is. */ + } + else if (SUCCEEDED(media_item_get_stream_type(sd, &major)) && IsEqualGUID(&major, &MFMediaType_Audio)) + { + if (FAILED(hr = MFCreateAudioRendererActivate((IMFActivate **)&sink))) + WARN("Failed to create SAR activation object, hr %#x.\n", hr); + }
- IMFTopology_AddNode(topology, sink_node); - } + if (sink) + { + hr = media_item_create_source_node(item, sd, &src_node); + if (SUCCEEDED(hr)) + hr = media_item_create_sink_node(sink, &sink_node);
- if (src_node && sink_node) + if (SUCCEEDED(hr)) + { + IMFTopology_AddNode(topology, src_node); + IMFTopology_AddNode(topology, sink_node); IMFTopologyNode_ConnectOutput(src_node, 0, sink_node, 0); + }
if (src_node) IMFTopologyNode_Release(src_node); if (sink_node) IMFTopologyNode_Release(sink_node); + + IUnknown_Release(sink); }
IMFStreamDescriptor_Release(sd);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/player.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index 87ddf613288..6a6f3b6cddc 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -1043,29 +1043,23 @@ static HRESULT media_item_create_sink_node(IUnknown *sink, IMFTopologyNode **nod static HRESULT media_item_create_topology(struct media_player *player, struct media_item *item, IMFTopology **out) { IMFTopologyNode *src_node, *sink_node; + BOOL selected, video_added = FALSE; IMFStreamDescriptor *sd; IMFTopology *topology; unsigned int idx; IUnknown *sink; - BOOL selected; HRESULT hr; GUID major;
if (FAILED(hr = MFCreateTopology(&topology))) return hr;
- /* Use first stream if none selected. */ - if (player->output_window) - { - FIXME("Video streams are not handled.\n"); - } - /* Set up branches for all selected streams. */
idx = 0; while (SUCCEEDED(IMFPresentationDescriptor_GetStreamDescriptorByIndex(item->pd, idx++, &selected, &sd))) { - if (!selected) + if (!selected || FAILED(media_item_get_stream_type(sd, &major))) { IMFStreamDescriptor_Release(sd); continue; @@ -1077,11 +1071,17 @@ static HRESULT media_item_create_topology(struct media_player *player, struct me { /* User sink is attached as-is. */ } - else if (SUCCEEDED(media_item_get_stream_type(sd, &major)) && IsEqualGUID(&major, &MFMediaType_Audio)) + else if (IsEqualGUID(&major, &MFMediaType_Audio)) { if (FAILED(hr = MFCreateAudioRendererActivate((IMFActivate **)&sink))) WARN("Failed to create SAR activation object, hr %#x.\n", hr); } + else if (IsEqualGUID(&major, &MFMediaType_Video) && player->output_window && !video_added) + { + if (FAILED(hr = MFCreateVideoRendererActivate(player->output_window, (IMFActivate **)&sink))) + WARN("Failed to create EVR activation object, hr %#x.\n", hr); + video_added = SUCCEEDED(hr); + }
if (sink) {
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/player.c | 66 ++++++++++++++++++++++++++++++++------------ 1 file changed, 48 insertions(+), 18 deletions(-)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index 6a6f3b6cddc..831e9fa9781 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -435,18 +435,62 @@ static HRESULT WINAPI media_item_SetStartStopPosition(IMFPMediaItem *iface, cons return E_NOTIMPL; }
+static HRESULT media_item_get_stream_type(IMFStreamDescriptor *sd, GUID *major) +{ + IMFMediaTypeHandler *handler; + HRESULT hr; + + if (SUCCEEDED(hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &handler))) + { + hr = IMFMediaTypeHandler_GetMajorType(handler, major); + IMFMediaTypeHandler_Release(handler); + } + + return hr; +} + +static HRESULT media_item_has_stream(struct media_item *item, const GUID *major, BOOL *has_stream, BOOL *is_selected) +{ + IMFStreamDescriptor *sd; + unsigned int idx = 0; + BOOL selected; + GUID guid; + + *has_stream = *is_selected = FALSE; + + while (SUCCEEDED(IMFPresentationDescriptor_GetStreamDescriptorByIndex(item->pd, idx++, &selected, &sd))) + { + if (SUCCEEDED(media_item_get_stream_type(sd, &guid)) && IsEqualGUID(&guid, major)) + { + *has_stream = TRUE; + *is_selected = selected; + } + + IMFStreamDescriptor_Release(sd); + + if (*has_stream && *is_selected) + break; + } + + return S_OK; +} + static HRESULT WINAPI media_item_HasVideo(IMFPMediaItem *iface, BOOL *has_video, BOOL *selected) { - FIXME("%p, %p, %p.\n", iface, has_video, selected); + struct media_item *item = impl_from_IMFPMediaItem(iface);
- return E_NOTIMPL; + TRACE("%p, %p, %p.\n", iface, has_video, selected); + + return media_item_has_stream(item, &MFMediaType_Video, has_video, selected); }
static HRESULT WINAPI media_item_HasAudio(IMFPMediaItem *iface, BOOL *has_audio, BOOL *selected) { - FIXME("%p, %p, %p.\n", iface, has_audio, selected); + struct media_item *item = impl_from_IMFPMediaItem(iface);
- return E_NOTIMPL; + TRACE("%p, %p, %p.\n", iface, has_audio, selected); + + return media_item_has_stream(item, &MFMediaType_Audio, has_audio, selected); }
static HRESULT WINAPI media_item_IsProtected(IMFPMediaItem *iface, BOOL *protected) @@ -1001,20 +1045,6 @@ static HRESULT WINAPI media_player_CreateMediaItemFromObject(IMFPMediaPlayer *if return hr; }
-static HRESULT media_item_get_stream_type(IMFStreamDescriptor *sd, GUID *major) -{ - IMFMediaTypeHandler *handler; - HRESULT hr; - - if (SUCCEEDED(hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &handler))) - { - hr = IMFMediaTypeHandler_GetMajorType(handler, major); - IMFMediaTypeHandler_Release(handler); - } - - return hr; -} - static HRESULT media_item_create_source_node(struct media_item *item, IMFStreamDescriptor *sd, IMFTopologyNode **node) {
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/Makefile.in | 2 +- dlls/mfplay/player.c | 15 +++++++++++++-- dlls/mfplay/tests/mfplay.c | 4 ++++ 3 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/dlls/mfplay/Makefile.in b/dlls/mfplay/Makefile.in index 8cd572bf638..303226f57f6 100644 --- a/dlls/mfplay/Makefile.in +++ b/dlls/mfplay/Makefile.in @@ -1,6 +1,6 @@ MODULE = mfplay.dll IMPORTLIB = mfplay -IMPORTS = mfplat mf ole32 user32 uuid mfuuid +IMPORTS = mfplat mf ole32 user32 uuid mfuuid strmiids
EXTRADLLFLAGS = -mno-cygwin -Wb,--prefer-native
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index 831e9fa9781..80c88721c78 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -1251,9 +1251,20 @@ static HRESULT WINAPI media_player_GetNativeVideoSize(IMFPMediaPlayer *iface, static HRESULT WINAPI media_player_GetIdealVideoSize(IMFPMediaPlayer *iface, SIZE *min_size, SIZE *max_size) { - FIXME("%p, %p, %p.\n", iface, min_size, max_size); + struct media_player *player = impl_from_IMFPMediaPlayer(iface); + IMFVideoDisplayControl *display_control; + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %p, %p.\n", iface, min_size, max_size); + + if (SUCCEEDED(hr = MFGetService((IUnknown *)player->session, &MR_VIDEO_RENDER_SERVICE, + &IID_IMFVideoDisplayControl, (void **)&display_control))) + { + hr = IMFVideoDisplayControl_GetIdealVideoSize(display_control, min_size, max_size); + IMFVideoDisplayControl_Release(display_control); + } + + return hr; }
static HRESULT WINAPI media_player_SetVideoSourceRect(IMFPMediaPlayer *iface, diff --git a/dlls/mfplay/tests/mfplay.c b/dlls/mfplay/tests/mfplay.c index 64a48cceaca..f11973ef939 100644 --- a/dlls/mfplay/tests/mfplay.c +++ b/dlls/mfplay/tests/mfplay.c @@ -122,6 +122,7 @@ static void test_create_player(void)
static void test_shutdown(void) { + SIZE min_size, max_size; IMFPMediaPlayer *player; float slowest, fastest; HRESULT hr; @@ -156,6 +157,9 @@ static void test_shutdown(void) ok(hr == S_OK, "Unexpected hr %#x.\n", hr); ok(state == MFP_MEDIAPLAYER_STATE_SHUTDOWN, "Unexpected state %d.\n", state);
+ hr = IMFPMediaPlayer_GetIdealVideoSize(player, &min_size, &max_size); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + hr = IMFPMediaPlayer_CreateMediaItemFromURL(player, L"url", TRUE, 0, &item); ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/player.c | 31 +++++++++++++++++++++++++++---- 1 file changed, 27 insertions(+), 4 deletions(-)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index 80c88721c78..cfbb3764905 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -1270,17 +1270,40 @@ static HRESULT WINAPI media_player_GetIdealVideoSize(IMFPMediaPlayer *iface, static HRESULT WINAPI media_player_SetVideoSourceRect(IMFPMediaPlayer *iface, MFVideoNormalizedRect const *rect) { - FIXME("%p, %p.\n", iface, rect); + struct media_player *player = impl_from_IMFPMediaPlayer(iface); + IMFVideoDisplayControl *display_control; + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, rect); + + if (SUCCEEDED(hr = MFGetService((IUnknown *)player->session, &MR_VIDEO_RENDER_SERVICE, + &IID_IMFVideoDisplayControl, (void **)&display_control))) + { + hr = IMFVideoDisplayControl_SetVideoPosition(display_control, rect, NULL); + IMFVideoDisplayControl_Release(display_control); + } + + return hr; }
static HRESULT WINAPI media_player_GetVideoSourceRect(IMFPMediaPlayer *iface, MFVideoNormalizedRect *rect) { - FIXME("%p, %p.\n", iface, rect); + struct media_player *player = impl_from_IMFPMediaPlayer(iface); + IMFVideoDisplayControl *display_control; + HRESULT hr; + RECT dest;
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, rect); + + if (SUCCEEDED(hr = MFGetService((IUnknown *)player->session, &MR_VIDEO_RENDER_SERVICE, + &IID_IMFVideoDisplayControl, (void **)&display_control))) + { + hr = IMFVideoDisplayControl_GetVideoPosition(display_control, rect, &dest); + IMFVideoDisplayControl_Release(display_control); + } + + return hr; }
static HRESULT WINAPI media_player_SetAspectRatioMode(IMFPMediaPlayer *iface, DWORD mode)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/player.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index cfbb3764905..708df7614e8 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -1308,17 +1308,39 @@ static HRESULT WINAPI media_player_GetVideoSourceRect(IMFPMediaPlayer *iface,
static HRESULT WINAPI media_player_SetAspectRatioMode(IMFPMediaPlayer *iface, DWORD mode) { - FIXME("%p, %u.\n", iface, mode); + struct media_player *player = impl_from_IMFPMediaPlayer(iface); + IMFVideoDisplayControl *display_control; + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %u.\n", iface, mode); + + if (SUCCEEDED(hr = MFGetService((IUnknown *)player->session, &MR_VIDEO_RENDER_SERVICE, + &IID_IMFVideoDisplayControl, (void **)&display_control))) + { + hr = IMFVideoDisplayControl_SetAspectRatioMode(display_control, mode); + IMFVideoDisplayControl_Release(display_control); + } + + return hr; }
static HRESULT WINAPI media_player_GetAspectRatioMode(IMFPMediaPlayer *iface, DWORD *mode) { - FIXME("%p, %p.\n", iface, mode); + struct media_player *player = impl_from_IMFPMediaPlayer(iface); + IMFVideoDisplayControl *display_control; + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, mode); + + if (SUCCEEDED(hr = MFGetService((IUnknown *)player->session, &MR_VIDEO_RENDER_SERVICE, + &IID_IMFVideoDisplayControl, (void **)&display_control))) + { + hr = IMFVideoDisplayControl_GetAspectRatioMode(display_control, mode); + IMFVideoDisplayControl_Release(display_control); + } + + return hr; }
static HRESULT WINAPI media_player_GetVideoWindow(IMFPMediaPlayer *iface, HWND *window)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/player.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index 708df7614e8..aa9392a1e97 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -1363,16 +1363,38 @@ static HRESULT WINAPI media_player_UpdateVideo(IMFPMediaPlayer *iface)
static HRESULT WINAPI media_player_SetBorderColor(IMFPMediaPlayer *iface, COLORREF color) { - FIXME("%p, %#x.\n", iface, color); + struct media_player *player = impl_from_IMFPMediaPlayer(iface); + IMFVideoDisplayControl *display_control; + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %#x.\n", iface, color); + + if (SUCCEEDED(hr = MFGetService((IUnknown *)player->session, &MR_VIDEO_RENDER_SERVICE, + &IID_IMFVideoDisplayControl, (void **)&display_control))) + { + hr = IMFVideoDisplayControl_SetBorderColor(display_control, color); + IMFVideoDisplayControl_Release(display_control); + } + + return hr; }
static HRESULT WINAPI media_player_GetBorderColor(IMFPMediaPlayer *iface, COLORREF *color) { - FIXME("%p, %p.\n", iface, color); + struct media_player *player = impl_from_IMFPMediaPlayer(iface); + IMFVideoDisplayControl *display_control; + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, color); + + if (SUCCEEDED(hr = MFGetService((IUnknown *)player->session, &MR_VIDEO_RENDER_SERVICE, + &IID_IMFVideoDisplayControl, (void **)&display_control))) + { + hr = IMFVideoDisplayControl_GetBorderColor(display_control, color); + IMFVideoDisplayControl_Release(display_control); + } + + return hr; }
static HRESULT WINAPI media_player_InsertEffect(IMFPMediaPlayer *iface, IUnknown *effect,
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplay/player.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/dlls/mfplay/player.c b/dlls/mfplay/player.c index aa9392a1e97..540a182a5ba 100644 --- a/dlls/mfplay/player.c +++ b/dlls/mfplay/player.c @@ -1243,9 +1243,20 @@ static HRESULT WINAPI media_player_SetMute(IMFPMediaPlayer *iface, BOOL mute) static HRESULT WINAPI media_player_GetNativeVideoSize(IMFPMediaPlayer *iface, SIZE *video, SIZE *arvideo) { - FIXME("%p, %p, %p.\n", iface, video, arvideo); + struct media_player *player = impl_from_IMFPMediaPlayer(iface); + IMFVideoDisplayControl *display_control; + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %p, %p.\n", iface, video, arvideo); + + if (SUCCEEDED(hr = MFGetService((IUnknown *)player->session, &MR_VIDEO_RENDER_SERVICE, + &IID_IMFVideoDisplayControl, (void **)&display_control))) + { + hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, video, arvideo); + IMFVideoDisplayControl_Release(display_control); + } + + return hr; }
static HRESULT WINAPI media_player_GetIdealVideoSize(IMFPMediaPlayer *iface,