[PATCH 2/4] evr: Implement input type validation for the mixer.
Nikolay Sivov
nsivov at codeweavers.com
Wed Jun 24 08:25:36 CDT 2020
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
dlls/evr/mixer.c | 73 +++++++++++++++++++++--
dlls/evr/tests/Makefile.in | 2 +-
dlls/evr/tests/evr.c | 116 ++++++++++++++++++++++++++++++++++++-
3 files changed, 185 insertions(+), 6 deletions(-)
diff --git a/dlls/evr/mixer.c b/dlls/evr/mixer.c
index 931554b5479..a65e82d4ca8 100644
--- a/dlls/evr/mixer.c
+++ b/dlls/evr/mixer.c
@@ -379,7 +379,7 @@ static HRESULT WINAPI video_mixer_transform_AddInputStreams(IMFTransform *iface,
static HRESULT WINAPI video_mixer_transform_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
IMFMediaType **type)
{
- FIXME("%p, %u, %u, %p.\n", iface, id, index, type);
+ TRACE("%p, %u, %u, %p.\n", iface, id, index, type);
return E_NOTIMPL;
}
@@ -392,11 +392,76 @@ static HRESULT WINAPI video_mixer_transform_GetOutputAvailableType(IMFTransform
return E_NOTIMPL;
}
-static HRESULT WINAPI video_mixer_transform_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
+static HRESULT video_mixer_init_dxva_videodesc(IMFMediaType *media_type, DXVA2_VideoDesc *video_desc)
{
- FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags);
+ const MFVIDEOFORMAT *video_format;
+ IMFVideoMediaType *video_type;
+ BOOL is_compressed = TRUE;
+ HRESULT hr = S_OK;
- return E_NOTIMPL;
+ if (FAILED(IMFMediaType_QueryInterface(media_type, &IID_IMFVideoMediaType, (void **)&video_type)))
+ return MF_E_INVALIDMEDIATYPE;
+
+ video_format = IMFVideoMediaType_GetVideoFormat(video_type);
+ IMFVideoMediaType_IsCompressedFormat(video_type, &is_compressed);
+
+ if (!video_format || !video_format->videoInfo.dwWidth || !video_format->videoInfo.dwHeight || is_compressed)
+ {
+ hr = MF_E_INVALIDMEDIATYPE;
+ goto done;
+ }
+
+ memset(video_desc, 0, sizeof(*video_desc));
+ video_desc->SampleWidth = video_format->videoInfo.dwWidth;
+ video_desc->SampleWidth = video_format->videoInfo.dwHeight;
+ video_desc->Format = video_format->surfaceInfo.Format;
+
+done:
+ IMFVideoMediaType_Release(video_type);
+
+ return hr;
+}
+
+static HRESULT WINAPI video_mixer_transform_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *media_type, DWORD flags)
+{
+ struct video_mixer *mixer = impl_from_IMFTransform(iface);
+ IDirectXVideoProcessorService *service;
+ DXVA2_VideoDesc video_desc;
+ HRESULT hr = E_NOTIMPL;
+ HANDLE handle;
+
+ TRACE("%p, %u, %p, %#x.\n", iface, id, media_type, flags);
+
+ if (id)
+ {
+ FIXME("Unimplemented for substreams.\n");
+ return E_NOTIMPL;
+ }
+
+ EnterCriticalSection(&mixer->cs);
+
+ if (!mixer->device_manager)
+ hr = MF_E_NOT_INITIALIZED;
+ else
+ {
+ if (SUCCEEDED(hr = IDirect3DDeviceManager9_OpenDeviceHandle(mixer->device_manager, &handle)))
+ {
+ if (SUCCEEDED(hr = IDirect3DDeviceManager9_GetVideoService(mixer->device_manager, handle,
+ &IID_IDirectXVideoProcessorService, (void **)&service)))
+ {
+ if (SUCCEEDED(hr = video_mixer_init_dxva_videodesc(media_type, &video_desc)))
+ {
+ FIXME("Probe for supported devices.\n");
+ hr = E_NOTIMPL;
+ }
+ }
+ IDirect3DDeviceManager9_CloseDeviceHandle(mixer->device_manager, handle);
+ }
+ }
+
+ LeaveCriticalSection(&mixer->cs);
+
+ return hr;
}
static HRESULT WINAPI video_mixer_transform_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
diff --git a/dlls/evr/tests/Makefile.in b/dlls/evr/tests/Makefile.in
index 8253c4d7fb4..5bd82277d1b 100644
--- a/dlls/evr/tests/Makefile.in
+++ b/dlls/evr/tests/Makefile.in
@@ -1,5 +1,5 @@
TESTDLL = evr.dll
-IMPORTS = mfuuid strmiids uuid dxguid ole32 oleaut32 evr d3d9 user32
+IMPORTS = dxva2 mfplat mfuuid strmiids uuid dxguid ole32 oleaut32 evr d3d9 user32
C_SRCS = \
evr.c
diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c
index 9365856d1eb..44819c1b387 100644
--- a/dlls/evr/tests/evr.c
+++ b/dlls/evr/tests/evr.c
@@ -19,16 +19,20 @@
*/
#define COBJMACROS
+
#include "dshow.h"
#include "wine/test.h"
#include "d3d9.h"
#include "evr.h"
+#include "mferror.h"
+#include "mfapi.h"
#include "initguid.h"
#include "dxva2api.h"
-#include "mferror.h"
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 HWND create_window(void)
{
RECT r = {0, 0, 640, 480};
@@ -626,16 +630,126 @@ done:
DestroyWindow(window);
}
+static void test_default_mixer_type_negotiation(void)
+{
+ IDirect3DDeviceManager9 *manager;
+ IMFVideoMediaType *video_type;
+ IMFMediaType *media_type;
+ IDirect3DDevice9 *device;
+ IMFTransform *transform;
+ IDirect3D9 *d3d;
+ HWND window;
+ HRESULT hr;
+ UINT token;
+
+ if (!pMFCreateVideoMediaTypeFromSubtype)
+ {
+ win_skip("Skipping mixer types tests.\n");
+ return;
+ }
+
+ hr = MFCreateVideoMixer(NULL, &IID_IDirect3DDevice9, &IID_IMFTransform, (void **)&transform);
+ ok(hr == S_OK, "Failed to create default mixer, hr %#x.\n", hr);
+
+ hr = IMFTransform_GetInputAvailableType(transform, 0, 0, &media_type);
+ ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr);
+
+ hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
+todo_wine
+ ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
+
+ hr = MFCreateMediaType(&media_type);
+ ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
+
+ hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Video);
+ ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
+
+ hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFVideoFormat_RGB32);
+ ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
+
+ hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
+ ok(hr == MF_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
+
+ /* Now try with device manager. */
+
+ window = create_window();
+ d3d = Direct3DCreate9(D3D_SDK_VERSION);
+ ok(!!d3d, "Failed to create a D3D object.\n");
+ if (!(device = create_device(d3d, window)))
+ {
+ skip("Failed to create a D3D device, skipping tests.\n");
+ goto done;
+ }
+
+ hr = DXVA2CreateDirect3DDeviceManager9(&token, &manager);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = IMFTransform_ProcessMessage(transform, MFT_MESSAGE_SET_D3D_MANAGER, (ULONG_PTR)manager);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ /* Now manager is not initialized. */
+ hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
+ ok(hr == DXVA2_E_NOT_INITIALIZED, "Unexpected hr %#x.\n", hr);
+
+ hr = IDirect3DDeviceManager9_ResetDevice(manager, device, token);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ /* And now type description is incomplete. */
+ hr = IMFTransform_SetInputType(transform, 0, media_type, 0);
+ ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
+ IMFMediaType_Release(media_type);
+
+ hr = pMFCreateVideoMediaTypeFromSubtype(&MFVideoFormat_RGB32, &video_type);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ /* Partially initialized type. */
+ hr = IMFTransform_SetInputType(transform, 0, (IMFMediaType *)video_type, 0);
+ ok(hr == MF_E_INVALIDMEDIATYPE, "Unexpected hr %#x.\n", hr);
+
+ /* Only required data - frame size and uncompressed marker. */
+ hr = IMFVideoMediaType_SetUINT64(video_type, &MF_MT_FRAME_SIZE, (UINT64)640 << 32 | 480);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ hr = IMFVideoMediaType_SetUINT32(video_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = IMFTransform_SetInputType(transform, 0, (IMFMediaType *)video_type, 0);
+todo_wine
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
+todo_wine
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ if (SUCCEEDED(hr))
+ {
+ ok(media_type != (IMFMediaType *)video_type, "Unexpected pointer.\n");
+ IMFMediaType_Release(media_type);
+ }
+
+ IMFVideoMediaType_Release(video_type);
+
+ IDirect3DDeviceManager9_Release(manager);
+
+ IDirect3DDevice9_Release(device);
+
+done:
+ IMFTransform_Release(transform);
+ IDirect3D9_Release(d3d);
+ DestroyWindow(window);
+}
+
START_TEST(evr)
{
CoInitialize(NULL);
+ pMFCreateVideoMediaTypeFromSubtype = (void *)GetProcAddress(GetModuleHandleA("mfplat.dll"), "MFCreateVideoMediaTypeFromSubtype");
+
test_aggregation();
test_interfaces();
test_enum_pins();
test_find_pin();
test_pin_info();
test_default_mixer();
+ test_default_mixer_type_negotiation();
test_surface_sample();
CoUninitialize();
--
2.27.0
More information about the wine-devel
mailing list