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(); }