evr: Implement input type validation for the mixer.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2020-06-24 16:25:36 +03:00 committed by Alexandre Julliard
parent 3ba3d228fb
commit 6ea77ccfeb
3 changed files with 185 additions and 6 deletions

View File

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

View File

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

View File

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