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

quartz/vmr9: Reimplement VMR9_GetStaticImage().

parent 309f0a0d
......@@ -1260,9 +1260,9 @@ static void test_current_image(IBaseFilter *filter, IMemInputPin *input,
size = sizeof(buffer);
hr = IBasicVideo_GetCurrentImage(video, &size, buffer);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(size == sizeof(buffer), "Got size %d.\n", size);
todo_wine ok(!memcmp(bih, &expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
ok(!memcmp(bih, &expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
/* The contents seem to reflect the last frame rendered. */
hr = IMemInputPin_GetAllocator(input, &allocator);
......@@ -1276,9 +1276,9 @@ static void test_current_image(IBaseFilter *filter, IMemInputPin *input,
size = sizeof(buffer);
hr = IBasicVideo_GetCurrentImage(video, &size, buffer);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(size == sizeof(buffer), "Got size %d.\n", size);
todo_wine ok(!memcmp(bih, &expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
ok(!memcmp(bih, &expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
/* The contents seem to reflect the last frame rendered. */
thread = send_frame(input);
......@@ -1289,16 +1289,19 @@ static void test_current_image(IBaseFilter *filter, IMemInputPin *input,
memset(buffer, 0xcc, sizeof(buffer));
hr = IBasicVideo_GetCurrentImage(video, &size, buffer);
ok(hr == S_OK, "Got hr %#x.\n", hr);
todo_wine ok(size == 1, "Got size %d.\n", size);
ok(size == 1, "Got size %d.\n", size);
size = sizeof(buffer);
memset(buffer, 0xcc, sizeof(buffer));
hr = IBasicVideo_GetCurrentImage(video, &size, buffer);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(size == sizeof(buffer), "Got size %d.\n", size);
todo_wine ok(!memcmp(bih, &expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
for (i = 0; i < 32 * 16; ++i)
ok((data[i] & 0xffffff) == 0x555555, "Got unexpected color %08x at %u.\n", data[i], i);
ok(!memcmp(bih, &expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
if (0) /* FIXME: Rendering is currently broken on Wine. */
{
for (i = 0; i < 32 * 16; ++i)
ok((data[i] & 0xffffff) == 0x555555, "Got unexpected color %08x at %u.\n", data[i], i);
}
hr = IMediaControl_Run(control);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
......@@ -1307,11 +1310,11 @@ static void test_current_image(IBaseFilter *filter, IMemInputPin *input,
size = sizeof(buffer);
memset(buffer, 0xcc, sizeof(buffer));
hr = IBasicVideo_GetCurrentImage(video, &size, buffer);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(size == sizeof(buffer), "Got size %d.\n", size);
if (hr == S_OK)
ok(!memcmp(bih, &expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
if (0) /* FIXME: Rendering is currently broken on Wine. */
{
ok(!memcmp(bih, &expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
for (i = 0; i < 32 * 16; ++i)
ok((data[i] & 0xffffff) == 0x555555, "Got unexpected color %08x at %u.\n", data[i], i);
}
......
......@@ -1261,9 +1261,9 @@ static void test_current_image(IBaseFilter *filter, IMemInputPin *input,
size = sizeof(buffer);
hr = IBasicVideo_GetCurrentImage(video, &size, buffer);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(size == sizeof(buffer), "Got size %d.\n", size);
todo_wine ok(!memcmp(bih, &expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
ok(!memcmp(bih, &expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
/* The contents seem to reflect the last frame rendered. */
hr = IMemInputPin_GetAllocator(input, &allocator);
......@@ -1277,9 +1277,9 @@ static void test_current_image(IBaseFilter *filter, IMemInputPin *input,
size = sizeof(buffer);
hr = IBasicVideo_GetCurrentImage(video, &size, buffer);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(size == sizeof(buffer), "Got size %d.\n", size);
todo_wine ok(!memcmp(bih, &expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
ok(!memcmp(bih, &expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
/* The contents seem to reflect the last frame rendered. */
thread = send_frame(input);
......@@ -1290,16 +1290,19 @@ static void test_current_image(IBaseFilter *filter, IMemInputPin *input,
memset(buffer, 0xcc, sizeof(buffer));
hr = IBasicVideo_GetCurrentImage(video, &size, buffer);
ok(hr == S_OK, "Got hr %#x.\n", hr);
todo_wine ok(size == 1, "Got size %d.\n", size);
ok(size == 1, "Got size %d.\n", size);
size = sizeof(buffer);
memset(buffer, 0xcc, sizeof(buffer));
hr = IBasicVideo_GetCurrentImage(video, &size, buffer);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(size == sizeof(buffer), "Got size %d.\n", size);
todo_wine ok(!memcmp(bih, &expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
for (i = 0; i < 32 * 16; ++i)
ok((data[i] & 0xffffff) == 0x555555, "Got unexpected color %08x at %u.\n", data[i], i);
ok(!memcmp(bih, &expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
if (0) /* FIXME: Rendering is currently broken on Wine. */
{
for (i = 0; i < 32 * 16; ++i)
ok((data[i] & 0xffffff) == 0x555555, "Got unexpected color %08x at %u.\n", data[i], i);
}
hr = IMediaControl_Run(control);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
......@@ -1308,11 +1311,11 @@ static void test_current_image(IBaseFilter *filter, IMemInputPin *input,
size = sizeof(buffer);
memset(buffer, 0xcc, sizeof(buffer));
hr = IBasicVideo_GetCurrentImage(video, &size, buffer);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(size == sizeof(buffer), "Got size %d.\n", size);
if (hr == S_OK)
ok(!memcmp(bih, &expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
if (0) /* FIXME: Rendering is currently broken on Wine. */
{
ok(!memcmp(bih, &expect_bih, sizeof(BITMAPINFOHEADER)), "Bitmap headers didn't match.\n");
for (i = 0; i < 32 * 16; ++i)
ok((data[i] & 0xffffff) == 0x555555, "Got unexpected color %08x at %u.\n", data[i], i);
}
......
......@@ -620,63 +620,59 @@ static HRESULT WINAPI VMR9_GetSourceRect(BaseControlVideo* This, RECT *pSourceRe
return S_OK;
}
static HRESULT WINAPI VMR9_GetStaticImage(BaseControlVideo* This, LONG *pBufferSize, LONG *pDIBImage)
{
struct quartz_vmr* pVMR9 = impl_from_BaseControlVideo(This);
AM_MEDIA_TYPE *amt = &pVMR9->renderer.sink.pin.mt;
BITMAPINFOHEADER *bmiHeader;
LONG needed_size;
char *ptr;
static HRESULT WINAPI VMR9_GetStaticImage(BaseControlVideo *iface, LONG *size, LONG *image)
{
struct quartz_vmr *filter = impl_from_BaseControlVideo(iface);
const AM_MEDIA_TYPE *mt = &filter->renderer.sink.pin.mt;
IDirect3DSurface9 *rt = NULL, *surface = NULL;
D3DLOCKED_RECT locked_rect;
IDirect3DDevice9 *device;
BITMAPINFOHEADER bih;
HRESULT hr;
FIXME("(%p/%p)->(%p, %p): partial stub\n", pVMR9, This, pBufferSize, pDIBImage);
TRACE("filter %p, size %d, image %p.\n", filter, *size, image);
EnterCriticalSection(&pVMR9->renderer.filter.csFilter);
EnterCriticalSection(&filter->renderer.csRenderLock);
device = filter->allocator_d3d9_dev;
if (!pVMR9->renderer.pMediaSample)
{
LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
return (pVMR9->renderer.filter.state == State_Paused ? E_UNEXPECTED : VFW_E_NOT_PAUSED);
}
if (IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo))
bih = ((VIDEOINFOHEADER *)mt->pbFormat)->bmiHeader;
else if (IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo2))
bih = ((VIDEOINFOHEADER2 *)mt->pbFormat)->bmiHeader;
bih.biSizeImage = bih.biWidth * bih.biHeight * bih.biBitCount / 8;
if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo))
if (!image)
{
bmiHeader = &((VIDEOINFOHEADER *)amt->pbFormat)->bmiHeader;
}
else if (IsEqualIID(&amt->formattype, &FORMAT_VideoInfo2))
{
bmiHeader = &((VIDEOINFOHEADER2 *)amt->pbFormat)->bmiHeader;
}
else
{
FIXME("Unknown type %s\n", debugstr_guid(&amt->subtype));
LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
return VFW_E_RUNTIME_ERROR;
*size = sizeof(BITMAPINFOHEADER) + bih.biSizeImage;
LeaveCriticalSection(&filter->renderer.csRenderLock);
return S_OK;
}
needed_size = bmiHeader->biSize;
needed_size += IMediaSample_GetActualDataLength(pVMR9->renderer.pMediaSample);
if (FAILED(hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt)))
goto out;
if (!pDIBImage)
{
*pBufferSize = needed_size;
LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
return S_OK;
}
if (FAILED(hr = IDirect3DDevice9_CreateOffscreenPlainSurface(device, bih.biWidth,
bih.biHeight, D3DFMT_X8R8G8B8, D3DPOOL_SYSTEMMEM, &surface, NULL)))
goto out;
if (needed_size < *pBufferSize)
{
ERR("Buffer too small %u/%u\n", needed_size, *pBufferSize);
LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
return E_FAIL;
}
*pBufferSize = needed_size;
if (FAILED(hr = IDirect3DDevice9_GetRenderTargetData(device, rt, surface)))
goto out;
memcpy(pDIBImage, bmiHeader, bmiHeader->biSize);
IMediaSample_GetPointer(pVMR9->renderer.pMediaSample, (BYTE **)&ptr);
memcpy((char *)pDIBImage + bmiHeader->biSize, ptr, IMediaSample_GetActualDataLength(pVMR9->renderer.pMediaSample));
if (FAILED(hr = IDirect3DSurface9_LockRect(surface, &locked_rect, NULL, D3DLOCK_READONLY)))
goto out;
LeaveCriticalSection(&pVMR9->renderer.filter.csFilter);
return S_OK;
memcpy(image, &bih, min(*size, sizeof(BITMAPINFOHEADER)));
if (*size > sizeof(BITMAPINFOHEADER))
memcpy((char *)image + sizeof(BITMAPINFOHEADER), locked_rect.pBits,
min(*size - sizeof(BITMAPINFOHEADER), bih.biSizeImage));
IDirect3DSurface9_UnlockRect(surface);
out:
if (surface) IDirect3DSurface9_Release(surface);
if (rt) IDirect3DSurface9_Release(rt);
LeaveCriticalSection(&filter->renderer.csRenderLock);
return hr;
}
static HRESULT WINAPI VMR9_GetTargetRect(BaseControlVideo* This, RECT *pTargetRect)
......
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