mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-15 02:44:46 +00:00
evr/presenter: Create a swapchain for given output window.
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
e19938f9db
commit
02d982de38
|
@ -77,6 +77,9 @@ struct video_presenter
|
|||
IMediaEventSink *event_sink;
|
||||
|
||||
IDirect3DDeviceManager9 *device_manager;
|
||||
IDirect3DSwapChain9 *swapchain;
|
||||
HANDLE hdevice;
|
||||
|
||||
IMFVideoSampleAllocator *allocator;
|
||||
struct streaming_thread thread;
|
||||
IMFMediaType *media_type;
|
||||
|
@ -164,6 +167,19 @@ static unsigned int get_gcd(unsigned int a, unsigned int b)
|
|||
return a;
|
||||
}
|
||||
|
||||
static HRESULT video_presenter_get_device(struct video_presenter *presenter, IDirect3DDevice9 **device)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
if (!presenter->hdevice)
|
||||
{
|
||||
if (FAILED(hr = IDirect3DDeviceManager9_OpenDeviceHandle(presenter->device_manager, &presenter->hdevice)))
|
||||
return hr;
|
||||
}
|
||||
|
||||
return IDirect3DDeviceManager9_LockDevice(presenter->device_manager, presenter->hdevice, device, TRUE);
|
||||
}
|
||||
|
||||
static void video_presenter_get_native_video_size(struct video_presenter *presenter)
|
||||
{
|
||||
IMFMediaType *media_type;
|
||||
|
@ -501,8 +517,13 @@ static ULONG WINAPI video_presenter_inner_Release(IUnknown *iface)
|
|||
video_presenter_clear_container(presenter);
|
||||
video_presenter_reset_media_type(presenter);
|
||||
DeleteCriticalSection(&presenter->cs);
|
||||
if (presenter->swapchain)
|
||||
IDirect3DSwapChain9_Release(presenter->swapchain);
|
||||
if (presenter->device_manager)
|
||||
{
|
||||
IDirect3DDeviceManager9_CloseDeviceHandle(presenter->device_manager, presenter->hdevice);
|
||||
IDirect3DDeviceManager9_Release(presenter->device_manager);
|
||||
}
|
||||
if (presenter->allocator)
|
||||
IMFVideoSampleAllocator_Release(presenter->allocator);
|
||||
heap_free(presenter);
|
||||
|
@ -995,9 +1016,32 @@ static HRESULT WINAPI video_presenter_control_GetAspectRatioMode(IMFVideoDisplay
|
|||
return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT video_presenter_create_swapchain(struct video_presenter *presenter)
|
||||
{
|
||||
D3DPRESENT_PARAMETERS present_params = { 0 };
|
||||
IDirect3DDevice9 *d3d_device;
|
||||
HRESULT hr;
|
||||
|
||||
if (SUCCEEDED(hr = video_presenter_get_device(presenter, &d3d_device)))
|
||||
{
|
||||
present_params.hDeviceWindow = presenter->video_window;
|
||||
present_params.Windowed = TRUE;
|
||||
present_params.SwapEffect = D3DSWAPEFFECT_COPY;
|
||||
present_params.Flags = D3DPRESENTFLAG_VIDEO;
|
||||
present_params.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE;
|
||||
hr = IDirect3DDevice9_CreateAdditionalSwapChain(d3d_device, &present_params, &presenter->swapchain);
|
||||
|
||||
IDirect3DDevice9_Release(d3d_device);
|
||||
IDirect3DDeviceManager9_UnlockDevice(presenter->device_manager, presenter->hdevice, FALSE);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI video_presenter_control_SetVideoWindow(IMFVideoDisplayControl *iface, HWND window)
|
||||
{
|
||||
struct video_presenter *presenter = impl_from_IMFVideoDisplayControl(iface);
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
TRACE("%p, %p.\n", iface, window);
|
||||
|
||||
|
@ -1005,10 +1049,16 @@ static HRESULT WINAPI video_presenter_control_SetVideoWindow(IMFVideoDisplayCont
|
|||
return E_INVALIDARG;
|
||||
|
||||
EnterCriticalSection(&presenter->cs);
|
||||
presenter->video_window = window;
|
||||
if (presenter->video_window != window)
|
||||
{
|
||||
if (presenter->swapchain)
|
||||
IDirect3DSwapChain9_Release(presenter->swapchain);
|
||||
presenter->video_window = window;
|
||||
hr = video_presenter_create_swapchain(presenter);
|
||||
}
|
||||
LeaveCriticalSection(&presenter->cs);
|
||||
|
||||
return S_OK;
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI video_presenter_control_GetVideoWindow(IMFVideoDisplayControl *iface, HWND *window)
|
||||
|
|
|
@ -1096,18 +1096,13 @@ done:
|
|||
|
||||
static void test_default_presenter(void)
|
||||
{
|
||||
D3DDEVICE_CREATION_PARAMETERS device_params = { 0 };
|
||||
D3DPRESENT_PARAMETERS present_params = { 0 };
|
||||
IMFVideoDisplayControl *display_control;
|
||||
IDirect3DSwapChain9 *swapchain;
|
||||
IMFVideoPresenter *presenter;
|
||||
IMFRateSupport *rate_support;
|
||||
IDirect3DDevice9 *d3d_device;
|
||||
IDirect3DDeviceManager9 *dm;
|
||||
IMFVideoDeviceID *deviceid;
|
||||
IMFGetService *gs;
|
||||
HWND hwnd, hwnd2;
|
||||
HANDLE handle;
|
||||
IUnknown *unk;
|
||||
DWORD flags;
|
||||
float rate;
|
||||
|
@ -1176,33 +1171,6 @@ static void test_default_presenter(void)
|
|||
hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFVideoDisplayControl, (void **)&display_control);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDeviceManager9_OpenDeviceHandle(dm, &handle);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDeviceManager9_LockDevice(dm, handle, &d3d_device, FALSE);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_GetCreationParameters(d3d_device, &device_params);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
ok(device_params.hFocusWindow == GetDesktopWindow(), "Unexpected window %p.\n", device_params.hFocusWindow);
|
||||
|
||||
hr = IDirect3DDevice9_GetSwapChain(d3d_device, 0, &swapchain);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_params);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
ok(present_params.hDeviceWindow == GetDesktopWindow(), "Unexpected device window.\n");
|
||||
ok(present_params.Windowed, "Unexpected windowed mode.\n");
|
||||
ok(present_params.SwapEffect == D3DSWAPEFFECT_COPY, "Unexpected swap effect.\n");
|
||||
ok(present_params.Flags & D3DPRESENTFLAG_VIDEO, "Unexpected flags %#x.\n", present_params.Flags);
|
||||
ok(present_params.PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE, "Unexpected present interval.\n");
|
||||
|
||||
IDirect3DDevice9_Release(d3d_device);
|
||||
|
||||
hr = IDirect3DDeviceManager9_UnlockDevice(dm, handle, FALSE);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
/* Video window */
|
||||
hwnd = create_window();
|
||||
ok(!!hwnd, "Failed to create a test window.\n");
|
||||
|
@ -1229,15 +1197,6 @@ static void test_default_presenter(void)
|
|||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
ok(hwnd2 == hwnd, "Unexpected window %p.\n", hwnd2);
|
||||
|
||||
/* Video position */
|
||||
hr = IDirect3DDeviceManager9_CloseDeviceHandle(dm, handle);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
IDirect3DDeviceManager9_Release(dm);
|
||||
|
||||
IMFVideoDisplayControl_Release(display_control);
|
||||
IMFGetService_Release(gs);
|
||||
|
||||
/* Rate support. */
|
||||
hr = IMFVideoPresenter_QueryInterface(presenter, &IID_IMFRateSupport, (void **)&rate_support);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
|
@ -1920,6 +1879,92 @@ static void test_presenter_ar_mode(void)
|
|||
IMFVideoDisplayControl_Release(display_control);
|
||||
}
|
||||
|
||||
static void test_presenter_video_window(void)
|
||||
{
|
||||
D3DDEVICE_CREATION_PARAMETERS device_params = { 0 };
|
||||
IMFVideoDisplayControl *display_control;
|
||||
IDirect3DDeviceManager9 *dm;
|
||||
IDirect3DDevice9 *d3d_device;
|
||||
HANDLE hdevice;
|
||||
HRESULT hr;
|
||||
IDirect3DSwapChain9 *swapchain;
|
||||
D3DPRESENT_PARAMETERS present_params = { 0 };
|
||||
HWND window;
|
||||
|
||||
hr = MFCreateVideoPresenter(NULL, &IID_IDirect3DDevice9, &IID_IMFVideoDisplayControl, (void **)&display_control);
|
||||
ok(hr == S_OK, "Failed to create default presenter, hr %#x.\n", hr);
|
||||
|
||||
hr = MFGetService((IUnknown *)display_control, &MR_VIDEO_ACCELERATION_SERVICE,
|
||||
&IID_IDirect3DDeviceManager9, (void **)&dm);
|
||||
|
||||
hr = IDirect3DDeviceManager9_OpenDeviceHandle(dm, &hdevice);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDeviceManager9_LockDevice(dm, hdevice, &d3d_device, FALSE);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_GetCreationParameters(d3d_device, &device_params);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
ok(device_params.hFocusWindow == GetDesktopWindow(), "Unexpected window %p.\n", device_params.hFocusWindow);
|
||||
|
||||
hr = IDirect3DDevice9_GetSwapChain(d3d_device, 0, &swapchain);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_params);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
ok(present_params.hDeviceWindow == GetDesktopWindow(), "Unexpected device window.\n");
|
||||
ok(present_params.Windowed, "Unexpected windowed mode.\n");
|
||||
ok(present_params.SwapEffect == D3DSWAPEFFECT_COPY, "Unexpected swap effect.\n");
|
||||
ok(present_params.Flags & D3DPRESENTFLAG_VIDEO, "Unexpected flags %#x.\n", present_params.Flags);
|
||||
ok(present_params.PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE, "Unexpected present interval.\n");
|
||||
|
||||
IDirect3DSwapChain9_Release(swapchain);
|
||||
IDirect3DDevice9_Release(d3d_device);
|
||||
|
||||
hr = IDirect3DDeviceManager9_UnlockDevice(dm, hdevice, FALSE);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
/* Setting window. */
|
||||
hr = IMFVideoDisplayControl_GetVideoWindow(display_control, &window);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
ok(!window, "Unexpected window %p.\n", window);
|
||||
|
||||
window = create_window();
|
||||
|
||||
hr = IMFVideoDisplayControl_SetVideoWindow(display_control, window);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
/* Device is not recreated or reset on window change. */
|
||||
hr = IDirect3DDeviceManager9_LockDevice(dm, hdevice, &d3d_device, FALSE);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDevice9_GetSwapChain(d3d_device, 0, &swapchain);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DSwapChain9_GetPresentParameters(swapchain, &present_params);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
ok(present_params.hDeviceWindow == GetDesktopWindow(), "Unexpected device window.\n");
|
||||
ok(present_params.Windowed, "Unexpected windowed mode.\n");
|
||||
ok(present_params.SwapEffect == D3DSWAPEFFECT_COPY, "Unexpected swap effect.\n");
|
||||
ok(present_params.Flags & D3DPRESENTFLAG_VIDEO, "Unexpected flags %#x.\n", present_params.Flags);
|
||||
ok(present_params.PresentationInterval == D3DPRESENT_INTERVAL_IMMEDIATE, "Unexpected present interval.\n");
|
||||
|
||||
IDirect3DSwapChain9_Release(swapchain);
|
||||
IDirect3DDevice9_Release(d3d_device);
|
||||
|
||||
hr = IDirect3DDeviceManager9_UnlockDevice(dm, hdevice, FALSE);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
hr = IDirect3DDeviceManager9_CloseDeviceHandle(dm, hdevice);
|
||||
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
|
||||
|
||||
IMFVideoDisplayControl_Release(display_control);
|
||||
|
||||
DestroyWindow(window);
|
||||
}
|
||||
|
||||
static void test_mixer_output_rectangle(void)
|
||||
{
|
||||
IMFVideoMixerControl *mixer_control;
|
||||
|
@ -2370,6 +2415,7 @@ START_TEST(evr)
|
|||
test_presenter_video_position();
|
||||
test_presenter_native_video_size();
|
||||
test_presenter_ar_mode();
|
||||
test_presenter_video_window();
|
||||
test_mixer_output_rectangle();
|
||||
test_mixer_zorder();
|
||||
test_mixer_samples();
|
||||
|
|
Loading…
Reference in a new issue