evr/mixer: Keep per-stream zorder configuration.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2020-10-06 14:49:01 +03:00 committed by Alexandre Julliard
parent 0b8b00216f
commit 9cb5077096
2 changed files with 158 additions and 6 deletions

View file

@ -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,

View file

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