amstream: Implement IDirectDrawMediaStream::SetDirectDraw().

Signed-off-by: Gijs Vermeulen <gijsvrm@gmail.com>
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Gijs Vermeulen 2020-06-25 20:56:59 +02:00 committed by Alexandre Julliard
parent 84566a0cc1
commit 51fce87c60
2 changed files with 83 additions and 52 deletions

View File

@ -35,6 +35,7 @@ struct ddraw_stream
IMemInputPin IMemInputPin_iface;
IPin IPin_iface;
LONG ref;
LONG sample_refs;
IMultiMediaStream* parent;
MSPID purpose_id;
@ -396,11 +397,35 @@ static HRESULT WINAPI ddraw_IDirectDrawMediaStream_GetDirectDraw(IDirectDrawMedi
}
static HRESULT WINAPI ddraw_IDirectDrawMediaStream_SetDirectDraw(IDirectDrawMediaStream *iface,
IDirectDraw *pDirectDraw)
IDirectDraw *ddraw)
{
FIXME("(%p)->(%p) stub!\n", iface, pDirectDraw);
struct ddraw_stream *stream = impl_from_IDirectDrawMediaStream(iface);
return E_NOTIMPL;
TRACE("stream %p, ddraw %p.\n", stream, ddraw);
EnterCriticalSection(&stream->cs);
if (stream->sample_refs)
{
HRESULT hr = (stream->ddraw == ddraw) ? S_OK : MS_E_SAMPLEALLOC;
LeaveCriticalSection(&stream->cs);
return hr;
}
if (stream->ddraw)
IDirectDraw_Release(stream->ddraw);
if (ddraw)
{
IDirectDraw_AddRef(ddraw);
stream->ddraw = ddraw;
}
else
stream->ddraw = NULL;
LeaveCriticalSection(&stream->cs);
return S_OK;
}
static HRESULT WINAPI ddraw_IDirectDrawMediaStream_CreateSample(IDirectDrawMediaStream *iface,
@ -951,6 +976,7 @@ HRESULT ddraw_stream_create(IUnknown *outer, void **out)
object->IMemInputPin_iface.lpVtbl = &ddraw_meminput_vtbl;
object->IPin_iface.lpVtbl = &ddraw_sink_vtbl;
object->ref = 1;
object->sample_refs = 0;
InitializeCriticalSection(&object->cs);
@ -1013,6 +1039,10 @@ static ULONG WINAPI ddraw_sample_Release(IDirectDrawStreamSample *iface)
TRACE("(%p)->(): new ref = %u\n", iface, ref);
EnterCriticalSection(&sample->parent->cs);
InterlockedDecrement(&sample->parent->sample_refs);
LeaveCriticalSection(&sample->parent->cs);
if (!ref)
{
if (sample->surface)
@ -1131,6 +1161,10 @@ static HRESULT ddrawstreamsample_create(struct ddraw_stream *parent, IDirectDraw
object->ref = 1;
object->parent = parent;
EnterCriticalSection(&parent->cs);
InterlockedIncrement(&parent->sample_refs);
LeaveCriticalSection(&parent->cs);
if (surface)
{
object->surface = surface;

View File

@ -4798,8 +4798,8 @@ static void test_ddrawstream_getsetdirectdraw(void)
/* The current ddraw is released when SetDirectDraw() is called. */
hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, NULL);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
todo_wine EXPECT_REF(ddraw, 2);
ok(hr == S_OK, "Got hr %#x.\n", hr);
EXPECT_REF(ddraw, 2);
hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw3);
ok(hr == S_OK, "Got hr %#x.\n", hr);
@ -4807,65 +4807,62 @@ static void test_ddrawstream_getsetdirectdraw(void)
if (ddraw3) IDirectDraw_Release(ddraw3);
hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, ddraw2);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(hr == S_OK, "Got hr %#x.\n", hr);
EXPECT_REF(ddraw, 3);
if (hr == S_OK)
{
hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw3);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(ddraw3 == ddraw2, "Expected ddraw %p, got %p.\n", ddraw2, ddraw3);
EXPECT_REF(ddraw, 4);
IDirectDraw_Release(ddraw3);
EXPECT_REF(ddraw, 3);
hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw3);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(ddraw3 == ddraw2, "Expected ddraw %p, got %p.\n", ddraw2, ddraw3);
EXPECT_REF(ddraw, 4);
IDirectDraw_Release(ddraw3);
EXPECT_REF(ddraw, 3);
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &sample);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &sample);
ok(hr == S_OK, "Got hr %#x.\n", hr);
/* SetDirectDraw() doesn't take an extra reference to the ddraw object
* if there are samples extant. */
hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, ddraw2);
ok(hr == S_OK, "Got hr %#x.\n", hr);
EXPECT_REF(ddraw, 3);
/* SetDirectDraw() doesn't take an extra reference to the ddraw object
* if there are samples extant. */
hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, ddraw2);
ok(hr == S_OK, "Got hr %#x.\n", hr);
EXPECT_REF(ddraw, 3);
hr = DirectDrawCreate(NULL, &ddraw3, NULL);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IDirectDraw_SetCooperativeLevel(ddraw3, GetDesktopWindow(), DDSCL_NORMAL);
ok(hr == DD_OK, "Got hr %#x.\n", hr);
EXPECT_REF(ddraw3, 1);
hr = DirectDrawCreate(NULL, &ddraw3, NULL);
ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IDirectDraw_SetCooperativeLevel(ddraw3, GetDesktopWindow(), DDSCL_NORMAL);
ok(hr == DD_OK, "Got hr %#x.\n", hr);
EXPECT_REF(ddraw3, 1);
hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, ddraw3);
ok(hr == MS_E_SAMPLEALLOC, "Got hr %#x.\n", hr);
hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, ddraw3);
ok(hr == MS_E_SAMPLEALLOC, "Got hr %#x.\n", hr);
hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw4);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(ddraw4 == ddraw2, "Expected ddraw %p, got %p.\n", ddraw2, ddraw4);
EXPECT_REF(ddraw, 4);
IDirectDraw_Release(ddraw4);
EXPECT_REF(ddraw, 3);
hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw4);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(ddraw4 == ddraw2, "Expected ddraw %p, got %p.\n", ddraw2, ddraw4);
EXPECT_REF(ddraw, 4);
IDirectDraw_Release(ddraw4);
EXPECT_REF(ddraw, 3);
ref = IDirectDrawStreamSample_Release(sample);
ok(!ref, "Got outstanding refcount %d.\n", ref);
ref = IDirectDrawStreamSample_Release(sample);
ok(!ref, "Got outstanding refcount %d.\n", ref);
hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, ddraw3);
ok(hr == S_OK, "Got hr %#x.\n", hr);
EXPECT_REF(ddraw, 2);
EXPECT_REF(ddraw3, 2);
hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, ddraw3);
ok(hr == S_OK, "Got hr %#x.\n", hr);
EXPECT_REF(ddraw, 2);
EXPECT_REF(ddraw3, 2);
hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw4);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(ddraw4 == ddraw3, "Expected ddraw %p, got %p.\n", ddraw3, ddraw4);
EXPECT_REF(ddraw3, 3);
IDirectDraw_Release(ddraw4);
EXPECT_REF(ddraw3, 2);
hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw4);
ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(ddraw4 == ddraw3, "Expected ddraw %p, got %p.\n", ddraw3, ddraw4);
EXPECT_REF(ddraw3, 3);
IDirectDraw_Release(ddraw4);
EXPECT_REF(ddraw3, 2);
hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, NULL);
ok(hr == S_OK, "Got hr %#x.\n", hr);
EXPECT_REF(ddraw3, 1);
hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, NULL);
ok(hr == S_OK, "Got hr %#x.\n", hr);
EXPECT_REF(ddraw3, 1);
ref = IDirectDraw_Release(ddraw3);
ok(!ref, "Got outstanding refcount %d.\n", ref);
}
ref = IDirectDraw_Release(ddraw3);
ok(!ref, "Got outstanding refcount %d.\n", ref);
EXPECT_REF(stream, 3);
IDirectDrawMediaStream_Release(ddraw_stream);