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; IMemInputPin IMemInputPin_iface;
IPin IPin_iface; IPin IPin_iface;
LONG ref; LONG ref;
LONG sample_refs;
IMultiMediaStream* parent; IMultiMediaStream* parent;
MSPID purpose_id; MSPID purpose_id;
@ -396,11 +397,35 @@ static HRESULT WINAPI ddraw_IDirectDrawMediaStream_GetDirectDraw(IDirectDrawMedi
} }
static HRESULT WINAPI ddraw_IDirectDrawMediaStream_SetDirectDraw(IDirectDrawMediaStream *iface, 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, 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->IMemInputPin_iface.lpVtbl = &ddraw_meminput_vtbl;
object->IPin_iface.lpVtbl = &ddraw_sink_vtbl; object->IPin_iface.lpVtbl = &ddraw_sink_vtbl;
object->ref = 1; object->ref = 1;
object->sample_refs = 0;
InitializeCriticalSection(&object->cs); InitializeCriticalSection(&object->cs);
@ -1013,6 +1039,10 @@ static ULONG WINAPI ddraw_sample_Release(IDirectDrawStreamSample *iface)
TRACE("(%p)->(): new ref = %u\n", iface, ref); TRACE("(%p)->(): new ref = %u\n", iface, ref);
EnterCriticalSection(&sample->parent->cs);
InterlockedDecrement(&sample->parent->sample_refs);
LeaveCriticalSection(&sample->parent->cs);
if (!ref) if (!ref)
{ {
if (sample->surface) if (sample->surface)
@ -1131,6 +1161,10 @@ static HRESULT ddrawstreamsample_create(struct ddraw_stream *parent, IDirectDraw
object->ref = 1; object->ref = 1;
object->parent = parent; object->parent = parent;
EnterCriticalSection(&parent->cs);
InterlockedIncrement(&parent->sample_refs);
LeaveCriticalSection(&parent->cs);
if (surface) if (surface)
{ {
object->surface = 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. */ /* The current ddraw is released when SetDirectDraw() is called. */
hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, NULL); hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, NULL);
todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
todo_wine EXPECT_REF(ddraw, 2); EXPECT_REF(ddraw, 2);
hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw3); hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw3);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
@ -4807,65 +4807,62 @@ static void test_ddrawstream_getsetdirectdraw(void)
if (ddraw3) IDirectDraw_Release(ddraw3); if (ddraw3) IDirectDraw_Release(ddraw3);
hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, ddraw2); 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); EXPECT_REF(ddraw, 3);
if (hr == S_OK) hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw3);
{ ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw3); ok(ddraw3 == ddraw2, "Expected ddraw %p, got %p.\n", ddraw2, ddraw3);
ok(hr == S_OK, "Got hr %#x.\n", hr); EXPECT_REF(ddraw, 4);
ok(ddraw3 == ddraw2, "Expected ddraw %p, got %p.\n", ddraw2, ddraw3); IDirectDraw_Release(ddraw3);
EXPECT_REF(ddraw, 4); EXPECT_REF(ddraw, 3);
IDirectDraw_Release(ddraw3);
EXPECT_REF(ddraw, 3);
hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &sample); hr = IDirectDrawMediaStream_CreateSample(ddraw_stream, NULL, NULL, 0, &sample);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
/* SetDirectDraw() doesn't take an extra reference to the ddraw object /* SetDirectDraw() doesn't take an extra reference to the ddraw object
* if there are samples extant. */ * if there are samples extant. */
hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, ddraw2); hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, ddraw2);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
EXPECT_REF(ddraw, 3); EXPECT_REF(ddraw, 3);
hr = DirectDrawCreate(NULL, &ddraw3, NULL); hr = DirectDrawCreate(NULL, &ddraw3, NULL);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IDirectDraw_SetCooperativeLevel(ddraw3, GetDesktopWindow(), DDSCL_NORMAL); hr = IDirectDraw_SetCooperativeLevel(ddraw3, GetDesktopWindow(), DDSCL_NORMAL);
ok(hr == DD_OK, "Got hr %#x.\n", hr); ok(hr == DD_OK, "Got hr %#x.\n", hr);
EXPECT_REF(ddraw3, 1); EXPECT_REF(ddraw3, 1);
hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, ddraw3); hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, ddraw3);
ok(hr == MS_E_SAMPLEALLOC, "Got hr %#x.\n", hr); ok(hr == MS_E_SAMPLEALLOC, "Got hr %#x.\n", hr);
hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw4); hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw4);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(ddraw4 == ddraw2, "Expected ddraw %p, got %p.\n", ddraw2, ddraw4); ok(ddraw4 == ddraw2, "Expected ddraw %p, got %p.\n", ddraw2, ddraw4);
EXPECT_REF(ddraw, 4); EXPECT_REF(ddraw, 4);
IDirectDraw_Release(ddraw4); IDirectDraw_Release(ddraw4);
EXPECT_REF(ddraw, 3); EXPECT_REF(ddraw, 3);
ref = IDirectDrawStreamSample_Release(sample); ref = IDirectDrawStreamSample_Release(sample);
ok(!ref, "Got outstanding refcount %d.\n", ref); ok(!ref, "Got outstanding refcount %d.\n", ref);
hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, ddraw3); hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, ddraw3);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
EXPECT_REF(ddraw, 2); EXPECT_REF(ddraw, 2);
EXPECT_REF(ddraw3, 2); EXPECT_REF(ddraw3, 2);
hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw4); hr = IDirectDrawMediaStream_GetDirectDraw(ddraw_stream, &ddraw4);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
ok(ddraw4 == ddraw3, "Expected ddraw %p, got %p.\n", ddraw3, ddraw4); ok(ddraw4 == ddraw3, "Expected ddraw %p, got %p.\n", ddraw3, ddraw4);
EXPECT_REF(ddraw3, 3); EXPECT_REF(ddraw3, 3);
IDirectDraw_Release(ddraw4); IDirectDraw_Release(ddraw4);
EXPECT_REF(ddraw3, 2); EXPECT_REF(ddraw3, 2);
hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, NULL); hr = IDirectDrawMediaStream_SetDirectDraw(ddraw_stream, NULL);
ok(hr == S_OK, "Got hr %#x.\n", hr); ok(hr == S_OK, "Got hr %#x.\n", hr);
EXPECT_REF(ddraw3, 1); EXPECT_REF(ddraw3, 1);
ref = IDirectDraw_Release(ddraw3); ref = IDirectDraw_Release(ddraw3);
ok(!ref, "Got outstanding refcount %d.\n", ref); ok(!ref, "Got outstanding refcount %d.\n", ref);
}
EXPECT_REF(stream, 3); EXPECT_REF(stream, 3);
IDirectDrawMediaStream_Release(ddraw_stream); IDirectDrawMediaStream_Release(ddraw_stream);