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;