Nikolay Sivov : evr: Implement input type validation for the mixer.

Alexandre Julliard julliard at winehq.org
Wed Jun 24 15:47:35 CDT 2020


Module: wine
Branch: master
Commit: 6ea77ccfebe56b2dd21b3e70bea86cc59b9495d5
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=6ea77ccfebe56b2dd21b3e70bea86cc59b9495d5

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Wed Jun 24 16:25:36 2020 +0300

evr: Implement input type validation for the mixer.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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 931554b547..a65e82d4ca 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 8253c4d7fb..5bd82277d1 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 9365856d1e..44819c1b38 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();




More information about the wine-cvs mailing list