Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/main.c | 8 +++++++- dlls/mf/tests/mf.c | 11 ++++++++++- include/mfidl.idl | 2 ++ 3 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/dlls/mf/main.c b/dlls/mf/main.c index 15c9e5e3c9a..3546caa6912 100644 --- a/dlls/mf/main.c +++ b/dlls/mf/main.c @@ -1291,12 +1291,18 @@ static const struct activate_funcs evr_activate_funcs =
HRESULT WINAPI MFCreateVideoRendererActivate(HWND hwnd, IMFActivate **activate) { + HRESULT hr; + TRACE("%p, %p.\n", hwnd, activate);
if (!activate) return E_POINTER;
- return create_activation_object(hwnd, &evr_activate_funcs, activate); + hr = create_activation_object(hwnd, &evr_activate_funcs, activate); + if (SUCCEEDED(hr)) + IMFActivate_SetUINT64(*activate, &MF_ACTIVATE_VIDEO_WINDOW, (ULONG_PTR)hwnd); + + return hr; }
struct simple_type_handler diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index c79ae69f91d..d252bab9b3b 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -3228,7 +3228,8 @@ static void test_evr(void) { IMFMediaSink *sink, *sink2; IMFActivate *activate; - DWORD flags; + DWORD flags, count; + UINT64 value; HRESULT hr;
hr = CoInitialize(NULL); @@ -3240,6 +3241,14 @@ static void test_evr(void) hr = MFCreateVideoRendererActivate(NULL, &activate); ok(hr == S_OK, "Failed to create activate object, hr %#x.\n", hr);
+ hr = IMFActivate_GetCount(activate, &count); + ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr); + ok(count == 1, "Unexpected count %u.\n", count); + + hr = IMFActivate_GetUINT64(activate, &MF_ACTIVATE_VIDEO_WINDOW, &value); + ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr); + ok(!value, "Unexpected value.\n"); + hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink); todo_wine ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr); diff --git a/include/mfidl.idl b/include/mfidl.idl index 89b1bdd05b8..2955d0d2f3b 100644 --- a/include/mfidl.idl +++ b/include/mfidl.idl @@ -1151,4 +1151,6 @@ cpp_quote("EXTERN_GUID(MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ID, 0xb10aaec3, 0xef cpp_quote("EXTERN_GUID(MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE, 0x6ba644ff, 0x27c5, 0x4d02, 0x98, 0x87, 0xc2, 0x86, 0x19, 0xfd, 0xb9, 0x1b);") cpp_quote("EXTERN_GUID(MF_AUDIO_RENDERER_ATTRIBUTE_STREAM_CATEGORY, 0xa9770471, 0x92ec, 0x4df4, 0x94, 0xfe, 0x81, 0xc3, 0x6f, 0x0c, 0x3a, 0x7a);")
+cpp_quote("EXTERN_GUID(MF_ACTIVATE_VIDEO_WINDOW, 0x9a2dbbdd, 0xf57e, 0x4162, 0x82, 0xb9, 0x68, 0x31, 0x37, 0x76, 0x82, 0xd3);") + cpp_quote("EXTERN_GUID(CLSID_VideoProcessorMFT, 0x88753b26, 0x5b24, 0x49bd, 0xb2, 0xe7, 0xc, 0x44, 0x5c, 0x78, 0xc9, 0x82);")
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/main.c | 7 +++++++ include/mfidl.idl | 16 ++++++++++++++++ 2 files changed, 23 insertions(+)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index ea6a0659c5c..6cd409d63b7 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -1646,12 +1646,18 @@ const char *debugstr_attr(const GUID *guid) X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_AUDCAP_SYMBOLIC_LINK), X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE11), X(MF_MT_USER_DATA), + X(MF_ACTIVATE_CUSTOM_VIDEO_MIXER_CLSID), X(MF_MT_MIN_MASTERING_LUMINANCE), + X(MF_ACTIVATE_CUSTOM_VIDEO_MIXER_ACTIVATE), + X(MF_ACTIVATE_CUSTOM_VIDEO_MIXER_FLAGS), + X(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_CLSID), X(MF_EVENT_STREAM_METADATA_SYSTEMID), + X(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_ACTIVATE), X(MF_MT_AUDIO_CHANNEL_MASK), X(MF_SOURCE_READER_DISCONNECT_MEDIASOURCE_ON_SHUTDOWN), X(MF_READWRITE_DISABLE_CONVERTERS), X(MF_MEDIA_ENGINE_BROWSER_COMPATIBILITY_MODE_IE_EDGE), + X(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_FLAGS), X(MF_MT_MINIMUM_DISPLAY_APERTURE), X(MFSampleExtension_Token), X(MF_DEVSOURCE_ATTRIBUTE_SOURCE_TYPE_VIDCAP_CATEGORY), @@ -1806,6 +1812,7 @@ const char *debugstr_attr(const GUID *guid) X(MF_MEDIA_ENGINE_COREWINDOW), X(MF_SOURCE_READER_DISABLE_CAMERA_PLUGINS), X(MF_MT_MPEG4_TRACK_TYPE), + X(MF_ACTIVATE_VIDEO_WINDOW), X(MF_MT_PAN_SCAN_APERTURE), X(MF_TOPOLOGY_RESOLUTION_STATUS), X(MF_MT_ORIGINAL_4CC), diff --git a/include/mfidl.idl b/include/mfidl.idl index 2955d0d2f3b..912e62ca350 100644 --- a/include/mfidl.idl +++ b/include/mfidl.idl @@ -1027,6 +1027,16 @@ interface IMFAudioPolicy : IUnknown HRESULT GetIconPath([out] LPWSTR *path); }
+enum +{ + MF_ACTIVATE_CUSTOM_MIXER_ALLOWFAIL = 0x00000001, +}; + +enum +{ + MF_ACTIVATE_CUSTOM_PRESENTER_ALLOWFAIL = 0x00000001, +}; + cpp_quote("#ifdef __cplusplus") cpp_quote("static inline HRESULT MFSetAttributeSize(IMFAttributes *attributes, REFGUID key, UINT32 width, UINT32 height)") cpp_quote("{") @@ -1152,5 +1162,11 @@ cpp_quote("EXTERN_GUID(MF_AUDIO_RENDERER_ATTRIBUTE_ENDPOINT_ROLE, 0x6ba644ff, 0x cpp_quote("EXTERN_GUID(MF_AUDIO_RENDERER_ATTRIBUTE_STREAM_CATEGORY, 0xa9770471, 0x92ec, 0x4df4, 0x94, 0xfe, 0x81, 0xc3, 0x6f, 0x0c, 0x3a, 0x7a);")
cpp_quote("EXTERN_GUID(MF_ACTIVATE_VIDEO_WINDOW, 0x9a2dbbdd, 0xf57e, 0x4162, 0x82, 0xb9, 0x68, 0x31, 0x37, 0x76, 0x82, 0xd3);") +cpp_quote("EXTERN_GUID(MF_ACTIVATE_CUSTOM_VIDEO_MIXER_CLSID, 0xba491360, 0xbe50, 0x451e, 0x95, 0xab, 0x6d, 0x4a, 0xcc, 0xc7, 0xda, 0xd8);") +cpp_quote("EXTERN_GUID(MF_ACTIVATE_CUSTOM_VIDEO_MIXER_ACTIVATE, 0xba491361, 0xbe50, 0x451e, 0x95, 0xab, 0x6d, 0x4a, 0xcc, 0xc7, 0xda, 0xd8);") +cpp_quote("EXTERN_GUID(MF_ACTIVATE_CUSTOM_VIDEO_MIXER_FLAGS, 0xba491362, 0xbe50, 0x451e, 0x95, 0xab, 0x6d, 0x4a, 0xcc, 0xc7, 0xda, 0xd8);") +cpp_quote("EXTERN_GUID(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_CLSID, 0xba491364, 0xbe50, 0x451e, 0x95, 0xab, 0x6d, 0x4a, 0xcc, 0xc7, 0xda, 0xd8);") +cpp_quote("EXTERN_GUID(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_ACTIVATE, 0xba491365, 0xbe50, 0x451e, 0x95, 0xab, 0x6d, 0x4a, 0xcc, 0xc7, 0xda, 0xd8);") +cpp_quote("EXTERN_GUID(MF_ACTIVATE_CUSTOM_VIDEO_PRESENTER_FLAGS, 0xba491366, 0xbe50, 0x451e, 0x95, 0xab, 0x6d, 0x4a, 0xcc, 0xc7, 0xda, 0xd8);")
cpp_quote("EXTERN_GUID(CLSID_VideoProcessorMFT, 0x88753b26, 0x5b24, 0x49bd, 0xb2, 0xe7, 0xc, 0x44, 0x5c, 0x78, 0xc9, 0x82);")
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/evr/evr.spec | 2 +- dlls/evr/mixer.c | 7 ++ dlls/evr/tests/Makefile.in | 2 +- dlls/evr/tests/evr.c | 142 +++++++++++++++++++++++++++++++++++++ include/evr.idl | 21 ++++++ include/mfidl.idl | 13 ++++ 6 files changed, 185 insertions(+), 2 deletions(-)
diff --git a/dlls/evr/evr.spec b/dlls/evr/evr.spec index ea87f16da15..214f2b81d85 100644 --- a/dlls/evr/evr.spec +++ b/dlls/evr/evr.spec @@ -19,7 +19,7 @@ @ stub MFCreateVideoPresenter2 @ stub MFCreateVideoPresenter @ stub MFCreateVideoSampleAllocator -@ stub MFCreateVideoSampleFromSurface +@ stdcall MFCreateVideoSampleFromSurface(ptr ptr) @ stub MFGetPlaneSize @ stub MFGetStrideForBitmapInfoHeader @ stub MFGetUncompressedVideoFormat diff --git a/dlls/evr/mixer.c b/dlls/evr/mixer.c index b651a56bff5..eaea037b693 100644 --- a/dlls/evr/mixer.c +++ b/dlls/evr/mixer.c @@ -685,3 +685,10 @@ HRESULT evr_mixer_create(IUnknown *outer, void **out)
return S_OK; } + +HRESULT WINAPI MFCreateVideoSampleFromSurface(IUnknown *surface, IMFSample **sample) +{ + FIXME("%p, %p.\n", surface, sample); + + return E_NOTIMPL; +} diff --git a/dlls/evr/tests/Makefile.in b/dlls/evr/tests/Makefile.in index 529c5354508..8253c4d7fb4 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 +IMPORTS = 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 9cf5d419198..9365856d1eb 100644 --- a/dlls/evr/tests/evr.c +++ b/dlls/evr/tests/evr.c @@ -29,6 +29,36 @@
static const WCHAR sink_id[] = {'E','V','R',' ','I','n','p','u','t','0',0};
+static HWND create_window(void) +{ + RECT r = {0, 0, 640, 480}; + + AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE); + + return CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE, + 0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL); +} + +static IDirect3DDevice9 *create_device(IDirect3D9 *d3d9, HWND focus_window) +{ + D3DPRESENT_PARAMETERS present_parameters = {0}; + IDirect3DDevice9 *device = NULL; + + present_parameters.BackBufferWidth = 640; + present_parameters.BackBufferHeight = 480; + present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8; + present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD; + present_parameters.hDeviceWindow = focus_window; + present_parameters.Windowed = TRUE; + present_parameters.EnableAutoDepthStencil = TRUE; + present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8; + + IDirect3D9_CreateDevice(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window, + D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, &device); + + return device; +} + static IBaseFilter *create_evr(void) { IBaseFilter *filter = NULL; @@ -485,6 +515,117 @@ static void test_default_mixer(void) IMFTransform_Release(transform); }
+static void test_surface_sample(void) +{ + IDirect3DSurface9 *backbuffer = NULL; + IMFMediaBuffer *buffer, *buffer2; + IDirect3DSwapChain9 *swapchain; + IDirect3DDevice9 *device; + DWORD count, length; + IMFSample *sample; + LONGLONG duration; + IDirect3D9 *d3d; + IUnknown *unk; + HWND window; + HRESULT hr; + BYTE *data; + + 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 = IDirect3DDevice9_GetSwapChain(device, 0, &swapchain); + ok(SUCCEEDED(hr), "Failed to get the implicit swapchain (%08x)\n", hr); + + hr = IDirect3DSwapChain9_GetBackBuffer(swapchain, 0, D3DBACKBUFFER_TYPE_MONO, &backbuffer); + ok(SUCCEEDED(hr), "Failed to get the back buffer (%08x)\n", hr); + ok(backbuffer != NULL, "The back buffer is NULL\n"); + + IDirect3DSwapChain9_Release(swapchain); + + hr = MFCreateVideoSampleFromSurface((IUnknown *)backbuffer, &sample); +todo_wine + ok(hr == S_OK, "Failed to create surface sample, hr %#x.\n", hr); + if (FAILED(hr)) goto done; + + hr = IMFSample_QueryInterface(sample, &IID_IMFTrackedSample, (void **)&unk); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + IUnknown_Release(unk); + + hr = IMFSample_QueryInterface(sample, &IID_IMFDesiredSample, (void **)&unk); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + IUnknown_Release(unk); + + hr = IMFSample_GetCount(sample, &count); + ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr); + ok(!count, "Unexpected attribute count.\n"); + + hr = IMFSample_GetBufferCount(sample, &count); + ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr); + ok(count == 1, "Unexpected attribute count.\n"); + + hr = IMFSample_GetTotalLength(sample, &length); + ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr); + ok(!length, "Unexpected length %u.\n", length); + + hr = IMFSample_GetSampleDuration(sample, &duration); + ok(hr == MF_E_NO_SAMPLE_DURATION, "Unexpected hr %#x.\n", hr); + + hr = IMFSample_GetSampleTime(sample, &duration); + ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#x.\n", hr); + + hr = IMFSample_GetBufferByIndex(sample, 0, &buffer); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFMediaBuffer_GetMaxLength(buffer, &length); + ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + + hr = IMFMediaBuffer_GetCurrentLength(buffer, &length); + ok(hr == S_OK, "Failed to get length, hr %#x.\n", hr); + ok(!length, "Unexpected length %u.\n", length); + + hr = IMFMediaBuffer_Lock(buffer, &data, NULL, NULL); + ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + + hr = IMFMediaBuffer_QueryInterface(buffer, &IID_IMF2DBuffer, (void **)&unk); + ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr); + + hr = IMFSample_AddBuffer(sample, buffer); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFSample_GetBufferCount(sample, &count); + ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr); + ok(count == 2, "Unexpected attribute count.\n"); + + hr = IMFSample_ConvertToContiguousBuffer(sample, &buffer2); + ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + + hr = IMFSample_CopyToBuffer(sample, buffer); + ok(hr == E_NOTIMPL, "Unexpected hr %#x.\n", hr); + + hr = IMFSample_RemoveAllBuffers(sample); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFSample_GetBufferCount(sample, &count); + ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr); + ok(!count, "Unexpected attribute count.\n"); + + IMFMediaBuffer_Release(buffer); + + IMFSample_Release(sample); + +done: + if (backbuffer) + IDirect3DSurface9_Release(backbuffer); + IDirect3D9_Release(d3d); + DestroyWindow(window); +} + START_TEST(evr) { CoInitialize(NULL); @@ -495,6 +636,7 @@ START_TEST(evr) test_find_pin(); test_pin_info(); test_default_mixer(); + test_surface_sample();
CoUninitialize(); } diff --git a/include/evr.idl b/include/evr.idl index 83603b92ccd..43afca1201a 100644 --- a/include/evr.idl +++ b/include/evr.idl @@ -198,4 +198,25 @@ interface IMFVideoMixerControl2 : IMFVideoMixerControl ); }
+[ + object, + uuid(56c294d0-753e-4260-8d61-a3d8820b1d54), + local +] +interface IMFDesiredSample : IUnknown +{ + HRESULT GetDesiredSampleTimeAndDuration( + [out] LONGLONG *sample_time, + [out] LONGLONG *sample_duration + ); + + void SetDesiredSampleTimeAndDuration( + [in] LONGLONG sample_time, + [in] LONGLONG sample_duration + ); + + void Clear(); +} + cpp_quote("HRESULT WINAPI MFCreateVideoMixer(IUnknown *owner, REFIID riid_device, REFIID riid, void **obj);") +cpp_quote("HRESULT WINAPI MFCreateVideoSampleFromSurface(IUnknown *surface, IMFSample **sample);") diff --git a/include/mfidl.idl b/include/mfidl.idl index 912e62ca350..35419756b5c 100644 --- a/include/mfidl.idl +++ b/include/mfidl.idl @@ -934,6 +934,19 @@ interface IMFQualityAdviseLimits : IUnknown HRESULT GetMinimumQualityLevel([out] MF_QUALITY_LEVEL *level); }
+[ + object, + uuid(245bf8e9-0755-40f7-88a5-ae0f18d55e17), + local +] +interface IMFTrackedSample : IUnknown +{ + HRESULT SetAllocator( + [in] IMFAsyncCallback *sample_allocator, + [in, unique] IUnknown *state + ); +} + typedef struct _MFT_REGISTRATION_INFO { CLSID clsid;