Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/evr/presenter.c | 14 ++++++++++++-- dlls/evr/tests/evr.c | 10 ++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/dlls/evr/presenter.c b/dlls/evr/presenter.c index eceabfd381d..8c455778d77 100644 --- a/dlls/evr/presenter.c +++ b/dlls/evr/presenter.c @@ -61,6 +61,7 @@ struct video_presenter HWND video_window; MFVideoNormalizedRect src_rect; RECT dst_rect; + DWORD rendering_prefs; unsigned int state; CRITICAL_SECTION cs; }; @@ -658,9 +659,18 @@ static HRESULT WINAPI video_presenter_control_SetRenderingPrefs(IMFVideoDisplayC
static HRESULT WINAPI video_presenter_control_GetRenderingPrefs(IMFVideoDisplayControl *iface, DWORD *flags) { - FIXME("%p, %p.\n", iface, flags); + struct video_presenter *presenter = impl_from_IMFVideoDisplayControl(iface);
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, flags); + + if (!flags) + return E_POINTER; + + EnterCriticalSection(&presenter->cs); + *flags = presenter->rendering_prefs; + LeaveCriticalSection(&presenter->cs); + + return S_OK; }
static HRESULT WINAPI video_presenter_control_SetFullscreen(IMFVideoDisplayControl *iface, BOOL fullscreen) diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c index db9546a945b..85eedbe6643 100644 --- a/dlls/evr/tests/evr.c +++ b/dlls/evr/tests/evr.c @@ -979,6 +979,7 @@ static void test_default_presenter(void) HWND hwnd, hwnd2; HANDLE handle; IUnknown *unk; + DWORD flags; float rate; HRESULT hr; GUID iid; @@ -1016,6 +1017,15 @@ static void test_default_presenter(void)
hr = IMFGetService_GetService(gs, &MR_VIDEO_RENDER_SERVICE, &IID_IMFVideoDisplayControl, (void **)&display_control); ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFVideoDisplayControl_GetRenderingPrefs(display_control, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + flags = 123; + hr = IMFVideoDisplayControl_GetRenderingPrefs(display_control, &flags); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(!flags, "Unexpected rendering flags %#x.\n", flags); + IMFVideoDisplayControl_Release(display_control);
hr = IMFGetService_GetService(gs, &MR_VIDEO_ACCELERATION_SERVICE, &IID_IDirect3DDeviceManager9, (void **)&dm);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/evr/presenter.c | 5 +++++ dlls/evr/tests/evr.c | 3 +++ 2 files changed, 8 insertions(+)
diff --git a/dlls/evr/presenter.c b/dlls/evr/presenter.c index 8c455778d77..9acbead7287 100644 --- a/dlls/evr/presenter.c +++ b/dlls/evr/presenter.c @@ -616,7 +616,12 @@ static HRESULT WINAPI video_presenter_control_GetVideoWindow(IMFVideoDisplayCont
TRACE("%p, %p.\n", iface, window);
+ if (!window) + return E_POINTER; + + EnterCriticalSection(&presenter->cs); *window = presenter->video_window; + LeaveCriticalSection(&presenter->cs);
return S_OK; } diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c index 85eedbe6643..53f1b02724d 100644 --- a/dlls/evr/tests/evr.c +++ b/dlls/evr/tests/evr.c @@ -1065,6 +1065,9 @@ static void test_default_presenter(void) hwnd = create_window(); ok(!!hwnd, "Failed to create a test window.\n");
+ hr = IMFVideoDisplayControl_GetVideoWindow(display_control, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + hwnd2 = hwnd; hr = IMFVideoDisplayControl_GetVideoWindow(display_control, &hwnd2); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/evr/presenter.c | 3 +++ dlls/evr/tests/evr.c | 6 ++++++ 2 files changed, 9 insertions(+)
diff --git a/dlls/evr/presenter.c b/dlls/evr/presenter.c index 9acbead7287..15ebcd80acc 100644 --- a/dlls/evr/presenter.c +++ b/dlls/evr/presenter.c @@ -603,6 +603,9 @@ static HRESULT WINAPI video_presenter_control_SetVideoWindow(IMFVideoDisplayCont
TRACE("%p, %p.\n", iface, window);
+ if (!IsWindow(window)) + return E_INVALIDARG; + EnterCriticalSection(&presenter->cs); presenter->video_window = window; LeaveCriticalSection(&presenter->cs); diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c index 53f1b02724d..79020e1ec49 100644 --- a/dlls/evr/tests/evr.c +++ b/dlls/evr/tests/evr.c @@ -1073,6 +1073,12 @@ static void test_default_presenter(void) ok(hr == S_OK, "Unexpected hr %#x.\n", hr); ok(hwnd2 == NULL, "Unexpected window %p.\n", hwnd2);
+ hr = IMFVideoDisplayControl_SetVideoWindow(display_control, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + hr = IMFVideoDisplayControl_SetVideoWindow(display_control, (HWND)0x1); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + hr = IMFVideoDisplayControl_SetVideoWindow(display_control, hwnd); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/evr/mixer.c | 83 +++++++++++++++++------- dlls/evr/tests/evr.c | 150 +++++++++++++++++++++++++++++++++++++------ 2 files changed, 190 insertions(+), 43 deletions(-)
diff --git a/dlls/evr/mixer.c b/dlls/evr/mixer.c index 4ada26d074f..da0bcb0a2db 100644 --- a/dlls/evr/mixer.c +++ b/dlls/evr/mixer.c @@ -41,6 +41,7 @@ struct input_stream unsigned int id; IMFAttributes *attributes; IMFVideoMediaType *media_type; + MFVideoNormalizedRect rect; };
struct output_stream @@ -145,15 +146,18 @@ static int video_mixer_compare_input_id(const void *a, const void *b) return 0; }
-static struct input_stream * video_mixer_get_input(const struct video_mixer *mixer, unsigned int id) +static HRESULT video_mixer_get_input(const struct video_mixer *mixer, unsigned int id, struct input_stream **stream) { - return bsearch(&id, mixer->inputs, mixer->input_count, sizeof(*mixer->inputs), video_mixer_compare_input_id); + *stream = bsearch(&id, mixer->inputs, mixer->input_count, sizeof(*mixer->inputs), video_mixer_compare_input_id); + return *stream ? S_OK : MF_E_INVALIDSTREAMNUMBER; }
static void video_mixer_init_input(struct input_stream *stream) { if (SUCCEEDED(MFCreateAttributes(&stream->attributes, 1))) IMFAttributes_SetUINT32(stream->attributes, &MF_SA_REQUIRED_SAMPLE_COUNT, 1); + stream->rect.left = stream->rect.top = 0.0f; + stream->rect.right = stream->rect.bottom = 1.0f; }
static void video_mixer_clear_types(struct video_mixer *mixer) @@ -352,19 +356,19 @@ static HRESULT WINAPI video_mixer_transform_GetInputStreamInfo(IMFTransform *ifa { struct video_mixer *mixer = impl_from_IMFTransform(iface); struct input_stream *input; - HRESULT hr = S_OK; + HRESULT hr;
TRACE("%p, %u, %p.\n", iface, id, info);
EnterCriticalSection(&mixer->cs); - if (!(input = video_mixer_get_input(mixer, id))) - hr = MF_E_INVALIDSTREAMNUMBER; - else + + if (SUCCEEDED(hr = video_mixer_get_input(mixer, id, &input))) { memset(info, 0, sizeof(*info)); if (id) info->dwFlags |= MFT_INPUT_STREAM_REMOVABLE | MFT_INPUT_STREAM_OPTIONAL; } + LeaveCriticalSection(&mixer->cs);
return hr; @@ -402,15 +406,13 @@ static HRESULT WINAPI video_mixer_transform_GetInputStreamAttributes(IMFTransfor { struct video_mixer *mixer = impl_from_IMFTransform(iface); struct input_stream *input; - HRESULT hr = S_OK; + HRESULT hr;
TRACE("%p, %u, %p.\n", iface, id, attributes);
EnterCriticalSection(&mixer->cs);
- if (!(input = video_mixer_get_input(mixer, id))) - hr = MF_E_INVALIDSTREAMNUMBER; - else + if (SUCCEEDED(hr = video_mixer_get_input(mixer, id, &input))) { *attributes = input->attributes; if (*attributes) @@ -434,17 +436,18 @@ static HRESULT WINAPI video_mixer_transform_DeleteInputStream(IMFTransform *ifac { struct video_mixer *mixer = impl_from_IMFTransform(iface); struct input_stream *input; - HRESULT hr = S_OK; unsigned int idx; + HRESULT hr;
TRACE("%p, %u.\n", iface, id);
+ if (!id) + return MF_E_INVALIDSTREAMNUMBER; + EnterCriticalSection(&mixer->cs);
/* Can't delete reference stream. */ - if (!id || !(input = video_mixer_get_input(mixer, id))) - hr = MF_E_INVALIDSTREAMNUMBER; - else + if (SUCCEEDED(hr = video_mixer_get_input(mixer, id, &input))) { mixer->input_count--; idx = input - mixer->inputs; @@ -736,13 +739,13 @@ static HRESULT WINAPI video_mixer_transform_GetInputCurrentType(IMFTransform *if { struct video_mixer *mixer = impl_from_IMFTransform(iface); struct input_stream *stream; - HRESULT hr = S_OK; + HRESULT hr;
TRACE("%p, %u, %p.\n", iface, id, type);
EnterCriticalSection(&mixer->cs);
- if ((stream = video_mixer_get_input(mixer, id))) + if (SUCCEEDED(hr = video_mixer_get_input(mixer, id, &stream))) { if (!stream->media_type) hr = MF_E_TRANSFORM_TYPE_NOT_SET; @@ -752,8 +755,6 @@ static HRESULT WINAPI video_mixer_transform_GetInputCurrentType(IMFTransform *if IMFMediaType_AddRef(*type); } } - else - hr = MF_E_INVALIDSTREAMNUMBER;
LeaveCriticalSection(&mixer->cs);
@@ -1029,20 +1030,54 @@ static HRESULT WINAPI video_mixer_control_GetStreamZOrder(IMFVideoMixerControl2 return E_NOTIMPL; }
-static HRESULT WINAPI video_mixer_control_SetStreamOutputRect(IMFVideoMixerControl2 *iface, DWORD stream_id, +static HRESULT WINAPI video_mixer_control_SetStreamOutputRect(IMFVideoMixerControl2 *iface, DWORD id, const MFVideoNormalizedRect *rect) { - FIXME("%p, %u, %p.\n", iface, stream_id, rect); + struct video_mixer *mixer = impl_from_IMFVideoMixerControl2(iface); + struct input_stream *stream; + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %u, %p.\n", iface, id, rect); + + if (!rect) + return E_POINTER; + + if (rect->left > rect->right || rect->top > rect->bottom || + rect->left < 0.0f || rect->top < 0.0f || rect->right > 1.0f || rect->bottom > 1.0f) + { + return E_INVALIDARG; + } + + EnterCriticalSection(&mixer->cs); + + if (SUCCEEDED(hr = video_mixer_get_input(mixer, id, &stream))) + stream->rect = *rect; + + LeaveCriticalSection(&mixer->cs); + + return hr; }
-static HRESULT WINAPI video_mixer_control_GetStreamOutputRect(IMFVideoMixerControl2 *iface, DWORD stream_id, +static HRESULT WINAPI video_mixer_control_GetStreamOutputRect(IMFVideoMixerControl2 *iface, DWORD id, MFVideoNormalizedRect *rect) { - FIXME("%p, %u, %p.\n", iface, stream_id, rect); + struct video_mixer *mixer = impl_from_IMFVideoMixerControl2(iface); + struct input_stream *stream; + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %u, %p.\n", iface, id, rect); + + if (!rect) + return E_POINTER; + + EnterCriticalSection(&mixer->cs); + + if (SUCCEEDED(hr = video_mixer_get_input(mixer, id, &stream))) + *rect = stream->rect; + + LeaveCriticalSection(&mixer->cs); + + return hr; }
static HRESULT WINAPI video_mixer_control_SetMixingPrefs(IMFVideoMixerControl2 *iface, DWORD flags) diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c index 79020e1ec49..fbefe5e02f4 100644 --- a/dlls/evr/tests/evr.c +++ b/dlls/evr/tests/evr.c @@ -33,6 +33,14 @@ static const WCHAR sink_id[] = {'E','V','R',' ','I','n','p','u','t','0',0};
static HRESULT (WINAPI *pMFCreateVideoMediaTypeFromSubtype)(const GUID *subtype, IMFVideoMediaType **video_type);
+static void set_rect(MFVideoNormalizedRect *rect, float left, float top, float right, float bottom) +{ + rect->left = left; + rect->top = top; + rect->right = right; + rect->bottom = bottom; +} + static HWND create_window(void) { RECT r = {0, 0, 640, 480}; @@ -1483,38 +1491,24 @@ static void test_presenter_video_position(void) ok(dst_rect.left == 0 && dst_rect.right == 10 && dst_rect.top == 0 && dst_rect.bottom == 10, "Unexpected destination rectangle %s.\n", wine_dbgstr_rect(&dst_rect));
- src_rect.left = src_rect.top = 0.0f; - src_rect.right = 2.0f; - src_rect.bottom = 1.0f; + set_rect(&src_rect, 0.0f, 0.0f, 2.0f, 1.0f); hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, NULL); ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
- src_rect.left = -0.1f; - src_rect.top = 0.0f; - src_rect.right = 0.9f; - src_rect.bottom = 1.0f; + set_rect(&src_rect, -0.1f, 0.0f, 0.9f, 1.0f); hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, NULL); ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
/* Flipped source rectangle. */ - src_rect.left = 0.5f; - src_rect.top = 0.0f; - src_rect.right = 0.4f; - src_rect.bottom = 1.0f; + set_rect(&src_rect, 0.5f, 0.0f, 0.4f, 1.0f); hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, NULL); ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
- src_rect.left = 0.0f; - src_rect.top = 0.5f; - src_rect.right = 0.4f; - src_rect.bottom = 0.1f; + set_rect(&src_rect, 0.0f, 0.5f, 0.4f, 0.1f); hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, NULL); ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
- src_rect.left = 0.1f; - src_rect.top = 0.2f; - src_rect.right = 0.8f; - src_rect.bottom = 0.9f; + set_rect(&src_rect, 0.1f, 0.2f, 0.8f, 0.9f); hr = IMFVideoDisplayControl_SetVideoPosition(display_control, &src_rect, NULL); ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
@@ -1559,6 +1553,122 @@ static void test_presenter_video_position(void) DestroyWindow(hwnd); }
+static void test_presenter_native_video_size(void) +{ + IMFTopologyServiceLookupClient *lookup_client; + IMFVideoDisplayControl *display_control; + IMFVideoPresenter *presenter; + struct test_host host; + IMFTransform *mixer; + SIZE size, ratio; + HRESULT hr; + + hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer); + ok(hr == S_OK, "Failed to create a mixer, hr %#x.\n", hr); + + hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoPresenter, (void **)&presenter); + ok(hr == S_OK, "Failed to create default presenter, hr %#x.\n", hr); + + hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&lookup_client); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&display_control); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, NULL, NULL); +todo_wine + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + memset(&size, 0xcc, sizeof(size)); + hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, &size, NULL); +todo_wine { + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(size.cx == 0 && size.cy == 0, "Unexpected size.\n"); +} + memset(&ratio, 0xcc, sizeof(ratio)); + hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, NULL, &ratio); +todo_wine { + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(ratio.cx == 0 && ratio.cy == 0, "Unexpected ratio.\n"); +} + hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFTopologyServiceLookupClient, (void **)&lookup_client); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + init_test_host(&host, mixer, presenter); + + hr = IMFTopologyServiceLookupClient_InitServicePointers(lookup_client, &host.IMFTopologyServiceLookup_iface); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFVideoDisplayControl_GetNativeVideoSize(display_control, &size, &ratio); +todo_wine { + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(size.cx == 0 && size.cy == 0, "Unexpected size.\n"); + ok(ratio.cx == 0 && ratio.cy == 0, "Unexpected ratio.\n"); +} + IMFVideoDisplayControl_Release(display_control); + IMFVideoPresenter_Release(presenter); + IMFTransform_Release(mixer); +} + +static void test_mixer_output_rectangle(void) +{ + IMFVideoMixerControl *mixer_control; + MFVideoNormalizedRect rect; + IMFTransform *mixer; + HRESULT hr; + + hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer); + ok(hr == S_OK, "Failed to create a mixer, hr %#x.\n", hr); + + hr = IMFTransform_QueryInterface(mixer, &IID_IMFVideoMixerControl, (void **)&mixer_control); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFVideoMixerControl_GetStreamOutputRect(mixer_control, 0, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + set_rect(&rect, 0.0f, 0.0f, 0.0f, 0.0f); + hr = IMFVideoMixerControl_GetStreamOutputRect(mixer_control, 0, &rect); + ok(hr == S_OK, "Failed to get output rect, hr %#x.\n", hr); + ok(rect.left == 0.0f && rect.top == 0.0f && rect.right == 1.0f && rect.bottom == 1.0f, + "Unexpected rectangle.\n"); + + hr = IMFVideoMixerControl_GetStreamOutputRect(mixer_control, 1, &rect); + ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); + + hr = IMFVideoMixerControl_GetStreamOutputRect(mixer_control, 1, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 1, &rect); + ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); + + hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 1, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + /* Wrong bounds. */ + set_rect(&rect, 0.0f, 0.0f, 1.1f, 1.0f); + hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 0, &rect); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + set_rect(&rect, -0.1f, 0.0f, 0.5f, 1.0f); + hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 0, &rect); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + /* Flipped. */ + set_rect(&rect, 1.0f, 0.0f, 0.0f, 1.0f); + hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 0, &rect); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + set_rect(&rect, 0.0f, 1.0f, 1.0f, 0.5f); + hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 0, &rect); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + hr = IMFVideoMixerControl_SetStreamOutputRect(mixer_control, 0, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + IMFVideoMixerControl_Release(mixer_control); + IMFTransform_Release(mixer); +} + START_TEST(evr) { CoInitialize(NULL); @@ -1577,6 +1687,8 @@ START_TEST(evr) test_MFCreateVideoMixerAndPresenter(); test_MFCreateVideoSampleAllocator(); test_presenter_video_position(); + test_presenter_native_video_size(); + test_mixer_output_rectangle();
CoUninitialize(); }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/evr/mixer.c | 59 +++++++++++++++++++++--- dlls/evr/tests/evr.c | 105 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 158 insertions(+), 6 deletions(-)
diff --git a/dlls/evr/mixer.c b/dlls/evr/mixer.c index da0bcb0a2db..107438b1f17 100644 --- a/dlls/evr/mixer.c +++ b/dlls/evr/mixer.c @@ -42,6 +42,7 @@ struct input_stream IMFAttributes *attributes; IMFVideoMediaType *media_type; MFVideoNormalizedRect rect; + unsigned int zorder; };
struct output_stream @@ -510,6 +511,8 @@ static HRESULT WINAPI video_mixer_transform_AddInputStreams(IMFTransform *iface,
if (SUCCEEDED(hr)) { + unsigned int zorder = mixer->input_count; + for (i = 0; i < count; ++i) { if ((input = bsearch(&ids[i], inputs, len, sizeof(*inputs), video_mixer_compare_input_id))) @@ -518,6 +521,13 @@ static HRESULT WINAPI video_mixer_transform_AddInputStreams(IMFTransform *iface, memcpy(&mixer->input_ids[mixer->input_count], ids, count * sizeof(*ids)); memcpy(mixer->inputs, inputs, len * sizeof(*inputs)); mixer->input_count += count; + + for (i = 0; i < count; ++i) + { + if (SUCCEEDED(video_mixer_get_input(mixer, ids[i], &input))) + input->zorder = zorder; + zorder++; + } } } LeaveCriticalSection(&mixer->cs); @@ -1016,18 +1026,55 @@ static ULONG WINAPI video_mixer_control_Release(IMFVideoMixerControl2 *iface) return IMFTransform_Release(&mixer->IMFTransform_iface); }
-static HRESULT WINAPI video_mixer_control_SetStreamZOrder(IMFVideoMixerControl2 *iface, DWORD stream_id, DWORD zorder) +static HRESULT WINAPI video_mixer_control_SetStreamZOrder(IMFVideoMixerControl2 *iface, DWORD id, DWORD zorder) { - FIXME("%p, %u, %u.\n", iface, stream_id, zorder); + struct video_mixer *mixer = impl_from_IMFVideoMixerControl2(iface); + struct input_stream *stream; + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %u, %u.\n", iface, id, zorder); + + /* Can't change reference stream. */ + if (!id && zorder) + return E_INVALIDARG; + + EnterCriticalSection(&mixer->cs); + + if (zorder >= mixer->input_count) + hr = E_INVALIDARG; + else if (SUCCEEDED(hr = video_mixer_get_input(mixer, id, &stream))) + { + /* Lowest zorder only applies to reference stream. */ + if (id && !zorder) + hr = MF_E_INVALIDREQUEST; + else + stream->zorder = zorder; + } + + LeaveCriticalSection(&mixer->cs); + + return hr; }
-static HRESULT WINAPI video_mixer_control_GetStreamZOrder(IMFVideoMixerControl2 *iface, DWORD stream_id, DWORD *zorder) +static HRESULT WINAPI video_mixer_control_GetStreamZOrder(IMFVideoMixerControl2 *iface, DWORD id, DWORD *zorder) { - FIXME("%p, %u, %p.\n", iface, stream_id, zorder); + struct video_mixer *mixer = impl_from_IMFVideoMixerControl2(iface); + struct input_stream *stream; + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %u, %p.\n", iface, id, zorder); + + if (!zorder) + return E_POINTER; + + EnterCriticalSection(&mixer->cs); + + if (SUCCEEDED(hr = video_mixer_get_input(mixer, id, &stream))) + *zorder = stream->zorder; + + LeaveCriticalSection(&mixer->cs); + + return hr; }
static HRESULT WINAPI video_mixer_control_SetStreamOutputRect(IMFVideoMixerControl2 *iface, DWORD id, diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c index fbefe5e02f4..70c7053efdf 100644 --- a/dlls/evr/tests/evr.c +++ b/dlls/evr/tests/evr.c @@ -1669,6 +1669,110 @@ static void test_mixer_output_rectangle(void) IMFTransform_Release(mixer); }
+static void test_mixer_zorder(void) +{ + IMFVideoMixerControl *mixer_control; + IMFTransform *mixer; + DWORD ids[2]; + DWORD value; + HRESULT hr; + + hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&mixer); + ok(hr == S_OK, "Failed to create a mixer, hr %#x.\n", hr); + + hr = IMFTransform_QueryInterface(mixer, &IID_IMFVideoMixerControl, (void **)&mixer_control); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 0, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 1, NULL); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + value = 1; + hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 0, &value); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(!value, "Unexpected value %u.\n", value); + + value = 1; + hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 1, &value); + ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); + + hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 0, 1); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 1, 1); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + /* Exceeds maximum stream number. */ + hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 0, 20); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + value = 1; + hr = IMFTransform_AddInputStreams(mixer, 1, &value); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + value = 0; + hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 1, &value); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(value == 1, "Unexpected zorder %u.\n", value); + + hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 1, 0); + ok(hr == MF_E_INVALIDREQUEST, "Unexpected hr %#x.\n", hr); + + hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 1, 2); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 0, 0); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + value = 2; + hr = IMFTransform_AddInputStreams(mixer, 1, &value); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + value = 0; + hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 2, &value); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(value == 2, "Unexpected zorder %u.\n", value); + + hr = IMFVideoMixerControl_SetStreamZOrder(mixer_control, 2, 1); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + value = 3; + hr = IMFTransform_AddInputStreams(mixer, 1, &value); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + value = 0; + hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 3, &value); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(value == 3, "Unexpected zorder %u.\n", value); + + hr = IMFTransform_DeleteInputStream(mixer, 1); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = IMFTransform_DeleteInputStream(mixer, 2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = IMFTransform_DeleteInputStream(mixer, 3); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + ids[0] = 2; + ids[1] = 1; + hr = IMFTransform_AddInputStreams(mixer, 2, ids); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + value = 0; + hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 1, &value); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(value == 2, "Unexpected zorder %u.\n", value); + + value = 0; + hr = IMFVideoMixerControl_GetStreamZOrder(mixer_control, 2, &value); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(value == 1, "Unexpected zorder %u.\n", value); + + IMFVideoMixerControl_Release(mixer_control); + IMFTransform_Release(mixer); +} + START_TEST(evr) { CoInitialize(NULL); @@ -1689,6 +1793,7 @@ START_TEST(evr) test_presenter_video_position(); test_presenter_native_video_size(); test_mixer_output_rectangle(); + test_mixer_zorder();
CoUninitialize(); }