Commit 9be491e8 authored by Zebediah Figura's avatar Zebediah Figura Committed by Alexandre Julliard

quartz: Implement sample allocation in the VMR7 presenter.

parent 830801d5
MODULE = quartz.dll
IMPORTLIB = quartz
IMPORTS = strmiids dxguid strmbase uuid dsound msacm32 msvfw32 ole32 oleaut32 rpcrt4 user32 gdi32 advapi32 winmm
IMPORTS = strmiids dxguid strmbase uuid ddraw dsound msacm32 msvfw32 ole32 oleaut32 rpcrt4 user32 gdi32 advapi32 winmm
SOURCES = \
acmwrapper.c \
......
TESTDLL = quartz.dll
IMPORTS = strmbase advapi32 d3d9 dsound msdmo msvfw32 ole32 oleaut32 user32 uuid winmm
IMPORTS = strmbase advapi32 d3d9 ddraw dsound msdmo msvfw32 ole32 oleaut32 user32 uuid winmm
SOURCES = \
acmwrapper.c \
......
......@@ -3153,6 +3153,176 @@ static void test_unconnected_eos(void)
ok(!ref, "Got outstanding refcount %ld.\n", ref);
}
static void test_default_presenter_allocate(void)
{
IDirectDrawSurface7 *frontbuffer, *backbuffer, *backbuffer2, *backbuffer3;
IDirectDraw7 *ddraw, *prev_ddraw = NULL;
IVMRSurfaceAllocator *allocator;
VMRALLOCATIONINFO info;
DDSURFACEDESC2 desc;
HRESULT hr;
LONG ref;
BITMAPINFOHEADER bitmap_header =
{
.biSize = sizeof(BITMAPINFOHEADER),
.biWidth = 32,
.biHeight = 16,
.biCompression = mmioFOURCC('Y','U','Y','2'),
.biBitCount = 16,
.biPlanes = 1,
};
static const struct
{
WORD depth;
DWORD compression;
DDPIXELFORMAT format;
}
tests[] =
{
{32, BI_RGB},
{12, mmioFOURCC('N','V','1','2')},
{12, mmioFOURCC('Y','V','1','2')},
{16, mmioFOURCC('U','Y','V','Y')},
{16, mmioFOURCC('Y','U','Y','2')},
};
hr = CoCreateInstance(&CLSID_AllocPresenter, NULL, CLSCTX_INPROC_SERVER,
&IID_IVMRSurfaceAllocator, (void **)&allocator);
ok(hr == S_OK, "Got hr %#lx.\n", hr);
hr = IVMRSurfaceAllocator_FreeSurface(allocator, 0);
ok(hr == S_OK, "Got hr %#lx.\n", hr);
info.dwFlags = AMAP_DIRECTED_FLIP | AMAP_ALLOW_SYSMEM;
info.dwMinBuffers = 2;
info.dwMaxBuffers = 2;
info.dwInterlaceFlags = 0;
info.szNativeSize.cx = info.szAspectRatio.cx = 640;
info.szNativeSize.cy = info.szAspectRatio.cy = 480;
info.lpHdr = &bitmap_header;
info.lpPixFmt = NULL;
for (unsigned int i = 0; i < ARRAY_SIZE(tests); ++i)
{
DWORD count = 2;
winetest_push_context("Compression %#lx, depth %u", tests[i].compression, tests[i].depth);
bitmap_header.biBitCount = tests[i].depth;
bitmap_header.biCompression = tests[i].compression;
hr = IVMRSurfaceAllocator_AllocateSurface(allocator, 0, &info, &count, &frontbuffer);
if (hr == VFW_E_DDRAW_CAPS_NOT_SUITABLE)
{
skip("Format is not supported.\n");
winetest_pop_context();
continue;
}
ok(hr == S_OK, "Got hr %#lx.\n", hr);
ok(count == 3, "Got count %lu.\n", count);
memset(&desc, 0, sizeof(desc));
desc.dwSize = sizeof(desc);
hr = IDirectDrawSurface7_GetSurfaceDesc(frontbuffer, &desc);
ok(hr == S_OK, "Got hr %#lx.\n", hr);
todo_wine ok(desc.dwFlags == (DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH | DDSD_PIXELFORMAT),
"Got flags %#lx.\n", desc.dwFlags);
todo_wine ok(desc.ddsCaps.dwCaps == (DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_FRONTBUFFER | DDSCAPS_FLIP), "Got caps %#lx.\n", desc.ddsCaps.dwCaps);
ok(!desc.ddsCaps.dwCaps2, "Got caps2 %#lx.\n", desc.ddsCaps.dwCaps2);
ok(!desc.ddsCaps.dwCaps3, "Got caps2 %#lx.\n", desc.ddsCaps.dwCaps3);
ok(!desc.ddsCaps.dwCaps4, "Got caps2 %#lx.\n", desc.ddsCaps.dwCaps4);
ok(desc.dwWidth == 32, "Got width %lu.\n", desc.dwWidth);
ok(desc.dwHeight == 16, "Got height %lu.\n", desc.dwHeight);
ok(desc.ddpfPixelFormat.dwSize == sizeof(desc.ddpfPixelFormat),
"Got size %lu.\n", desc.ddpfPixelFormat.dwSize);
if (tests[i].compression)
{
ok(desc.ddpfPixelFormat.dwFlags == DDPF_FOURCC, "Got flags %#lx.\n", desc.ddpfPixelFormat.dwFlags);
ok(desc.ddpfPixelFormat.dwFourCC == bitmap_header.biCompression,
"Got fourcc %08lx.\n", desc.ddpfPixelFormat.dwFourCC);
}
else
{
ok(desc.ddpfPixelFormat.dwFlags == DDPF_RGB, "Got flags %#lx.\n", desc.ddpfPixelFormat.dwFlags);
ok(desc.ddpfPixelFormat.dwRGBBitCount == 32, "Got depth %lu.\n", desc.ddpfPixelFormat.dwRGBBitCount);
ok(desc.ddpfPixelFormat.dwRBitMask == 0x00ff0000, "Got red mask %#lx.\n", desc.ddpfPixelFormat.dwRBitMask);
ok(desc.ddpfPixelFormat.dwGBitMask == 0x0000ff00, "Got green mask %#lx.\n", desc.ddpfPixelFormat.dwGBitMask);
ok(desc.ddpfPixelFormat.dwBBitMask == 0x000000ff, "Got blue mask %#lx.\n", desc.ddpfPixelFormat.dwBBitMask);
}
desc.ddsCaps.dwCaps = DDSCAPS_FLIP;
hr = IDirectDrawSurface7_GetAttachedSurface(frontbuffer, &desc.ddsCaps, &backbuffer);
ok(hr == S_OK, "Got hr %#lx.\n", hr);
memset(&desc, 0, sizeof(desc));
desc.dwSize = sizeof(desc);
hr = IDirectDrawSurface7_GetSurfaceDesc(backbuffer, &desc);
ok(hr == S_OK, "Got hr %#lx.\n", hr);
todo_wine ok(desc.dwFlags == (DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH | DDSD_PIXELFORMAT),
"Got flags %#lx.\n", desc.dwFlags);
todo_wine ok(desc.ddsCaps.dwCaps == (DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_BACKBUFFER | DDSCAPS_FLIP), "Got caps %#lx.\n", desc.ddsCaps.dwCaps);
desc.ddsCaps.dwCaps = DDSCAPS_FLIP;
hr = IDirectDrawSurface7_GetAttachedSurface(backbuffer, &desc.ddsCaps, &backbuffer2);
ok(hr == S_OK, "Got hr %#lx.\n", hr);
memset(&desc, 0, sizeof(desc));
desc.dwSize = sizeof(desc);
hr = IDirectDrawSurface7_GetSurfaceDesc(backbuffer2, &desc);
ok(hr == S_OK, "Got hr %#lx.\n", hr);
todo_wine ok(desc.dwFlags == (DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PITCH | DDSD_PIXELFORMAT),
"Got flags %#lx.\n", desc.dwFlags);
todo_wine ok(desc.ddsCaps.dwCaps == (DDSCAPS_LOCALVIDMEM | DDSCAPS_VIDEOMEMORY | DDSCAPS_OFFSCREENPLAIN
| DDSCAPS_FLIP), "Got caps %#lx.\n", desc.ddsCaps.dwCaps);
desc.ddsCaps.dwCaps = DDSCAPS_VIDEOMEMORY;
hr = IDirectDrawSurface7_GetAttachedSurface(backbuffer2, &desc.ddsCaps, &backbuffer3);
todo_wine_if (tests[i].compression) ok(hr == S_OK, "Got hr %#lx.\n", hr);
if (hr == S_OK)
{
ok(backbuffer3 == frontbuffer, "Expected only 2 backbuffers.\n");
IDirectDrawSurface7_Release(backbuffer3);
}
IDirectDrawSurface7_Release(backbuffer2);
IDirectDrawSurface7_Release(backbuffer);
hr = IDirectDrawSurface7_GetDDInterface(frontbuffer, (void **)&ddraw);
ok(hr == S_OK, "Got hr %#lx.\n", hr);
if (prev_ddraw)
{
ok(ddraw == prev_ddraw, "Expected the same ddraw object.\n");
IDirectDraw7_Release(ddraw);
}
else
{
prev_ddraw = ddraw;
}
/* AllocateSurface does *not* give the application a reference to the
* surface. */
IDirectDrawSurface7_AddRef(frontbuffer);
hr = IVMRSurfaceAllocator_FreeSurface(allocator, 0);
ok(hr == S_OK, "Got hr %#lx.\n", hr);
ref = IDirectDrawSurface7_Release(frontbuffer);
ok(!ref, "Got outstanding refcount %ld.\n", ref);
winetest_pop_context();
}
ref = IVMRSurfaceAllocator_Release(allocator);
ok(!ref, "Got outstanding refcount %ld.\n", ref);
ref = IDirectDraw7_Release(prev_ddraw);
ok(!ref, "Got outstanding refcount %ld.\n", ref);
}
START_TEST(vmr7)
{
CoInitialize(NULL);
......@@ -3172,6 +3342,7 @@ START_TEST(vmr7)
test_basic_video();
test_windowless_size();
test_unconnected_eos();
test_default_presenter_allocate();
CoUninitialize();
}
......@@ -30,6 +30,9 @@ struct vmr7_presenter
IVMRSurfaceAllocator IVMRSurfaceAllocator_iface;
IVMRWindowlessControl IVMRWindowlessControl_iface;
LONG refcount;
IDirectDraw7 *ddraw;
IDirectDrawSurface7 *frontbuffer;
};
static struct vmr7_presenter *impl_from_IVMRImagePresenter(IVMRImagePresenter *iface)
......@@ -76,7 +79,12 @@ static ULONG WINAPI image_presenter_Release(IVMRImagePresenter *iface)
TRACE("%p decreasing refcount to %lu.\n", presenter, refcount);
if (!refcount)
{
if (presenter->frontbuffer)
IDirectDrawSurface7_Release(presenter->frontbuffer);
IDirectDraw7_Release(presenter->ddraw);
free(presenter);
}
return refcount;
}
......@@ -136,16 +144,66 @@ static ULONG WINAPI surface_allocator_Release(IVMRSurfaceAllocator *iface)
}
static HRESULT WINAPI surface_allocator_AllocateSurface(IVMRSurfaceAllocator *iface,
DWORD_PTR id, VMRALLOCATIONINFO *info, DWORD *count, IDirectDrawSurface7 **surfaces)
DWORD_PTR id, VMRALLOCATIONINFO *info, DWORD *count, IDirectDrawSurface7 **surface)
{
FIXME("iface %p, id %#Ix, info %p, count %p, surfaces %p, stub!\n", iface, id, info, count, surfaces);
struct vmr7_presenter *presenter = impl_from_IVMRSurfaceAllocator(iface);
DDSURFACEDESC2 surface_desc = {.dwSize = sizeof(surface_desc)};
HRESULT hr;
TRACE("presenter %p, id %#Ix, info %p, count %p, surface %p.\n", presenter, id, info, count, surface);
surface_desc.dwFlags = DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT | DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
surface_desc.dwWidth = info->lpHdr->biWidth;
surface_desc.dwHeight = info->lpHdr->biHeight;
surface_desc.ddpfPixelFormat.dwSize = sizeof(surface_desc.ddpfPixelFormat);
surface_desc.ddsCaps.dwCaps = DDSCAPS_FLIP | DDSCAPS_COMPLEX | DDSCAPS_OFFSCREENPLAIN;
surface_desc.dwBackBufferCount = *count;
if (info->lpHdr->biCompression == BI_RGB)
{
if (info->lpHdr->biBitCount != 32)
{
FIXME("Unhandled bit depth %u.\n", info->lpHdr->biBitCount);
return E_NOTIMPL;
}
surface_desc.ddpfPixelFormat.dwFlags = DDPF_RGB;
surface_desc.ddpfPixelFormat.dwRGBBitCount = 32;
surface_desc.ddpfPixelFormat.dwRBitMask = 0x00ff0000;
surface_desc.ddpfPixelFormat.dwGBitMask = 0x0000ff00;
surface_desc.ddpfPixelFormat.dwBBitMask = 0x000000ff;
}
else
{
surface_desc.ddpfPixelFormat.dwFlags = DDPF_FOURCC;
surface_desc.ddpfPixelFormat.dwFourCC = info->lpHdr->biCompression;
}
if (FAILED(hr = IDirectDraw7_CreateSurface(presenter->ddraw,
&surface_desc, &presenter->frontbuffer, NULL)))
{
WARN("Failed to create surface, hr %#lx.\n", hr);
return hr;
}
*surface = presenter->frontbuffer;
++*count;
return S_OK;
}
static HRESULT WINAPI surface_allocator_FreeSurface(IVMRSurfaceAllocator *iface, DWORD_PTR id)
{
FIXME("iface %p, id %#Ix, stub!\n", iface, id);
return E_NOTIMPL;
struct vmr7_presenter *presenter = impl_from_IVMRSurfaceAllocator(iface);
DDSURFACEDESC2 surface_desc = {.dwSize = sizeof(surface_desc)};
TRACE("presenter %p, id %#Ix.\n", presenter, id);
if (presenter->frontbuffer)
{
IDirectDrawSurface7_Release(presenter->frontbuffer);
presenter->frontbuffer = NULL;
}
return S_OK;
}
static HRESULT WINAPI surface_allocator_PrepareSurface(IVMRSurfaceAllocator *iface,
......@@ -324,6 +382,7 @@ static const IVMRWindowlessControlVtbl windowless_control_vtbl =
HRESULT vmr7_presenter_create(IUnknown *outer, IUnknown **out)
{
struct vmr7_presenter *object;
HRESULT hr;
TRACE("outer %p, out %p.\n", outer, out);
......@@ -337,6 +396,16 @@ HRESULT vmr7_presenter_create(IUnknown *outer, IUnknown **out)
object->IVMRWindowlessControl_iface.lpVtbl = &windowless_control_vtbl;
object->refcount = 1;
if (FAILED(hr = DirectDrawCreateEx(NULL, (void **)&object->ddraw, &IID_IDirectDraw7, NULL)))
{
ERR("Failed to create ddraw object, hr %#lx.\n", hr);
free(object);
return hr;
}
if (FAILED(hr = IDirectDraw7_SetCooperativeLevel(object->ddraw, NULL, DDSCL_NORMAL)))
ERR("Failed to set cooperative level, hr %#lx.\n", hr);
TRACE("Created VMR7 default presenter %p.\n", object);
*out = (IUnknown *)&object->IVMRSurfaceAllocator_iface;
return S_OK;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment