amstream: Implement SSUPDATE_CONTINUOUS flag in IDirectDrawStreamSample::Update.
Signed-off-by: Anton Baskanov <baskanov@gmail.com> Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
4ced409adb
commit
aaf461b7d2
|
@ -75,10 +75,12 @@ struct ddraw_sample
|
|||
RECT rect;
|
||||
STREAM_TIME start_time;
|
||||
STREAM_TIME end_time;
|
||||
BOOL continuous_update;
|
||||
CONDITION_VARIABLE update_cv;
|
||||
|
||||
struct list entry;
|
||||
HRESULT update_hr;
|
||||
BOOL busy;
|
||||
};
|
||||
|
||||
static HRESULT ddrawstreamsample_create(struct ddraw_stream *parent, IDirectDrawSurface *surface,
|
||||
|
@ -86,6 +88,7 @@ static HRESULT ddrawstreamsample_create(struct ddraw_stream *parent, IDirectDraw
|
|||
|
||||
static void remove_queued_update(struct ddraw_sample *sample)
|
||||
{
|
||||
sample->busy = FALSE;
|
||||
list_remove(&sample->entry);
|
||||
WakeConditionVariable(&sample->update_cv);
|
||||
}
|
||||
|
@ -1348,7 +1351,16 @@ static HRESULT WINAPI ddraw_meminput_Receive(IMemInputPin *iface, IMediaSample *
|
|||
sample->update_hr = process_update(sample, top_down_stride, top_down_pointer,
|
||||
start_stream_time, end_stream_time);
|
||||
|
||||
remove_queued_update(sample);
|
||||
if (sample->continuous_update && SUCCEEDED(sample->update_hr))
|
||||
{
|
||||
list_remove(&sample->entry);
|
||||
list_add_tail(&sample->parent->update_queue, &sample->entry);
|
||||
}
|
||||
else
|
||||
{
|
||||
remove_queued_update(sample);
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&stream->cs);
|
||||
return S_OK;
|
||||
}
|
||||
|
@ -1540,12 +1552,6 @@ static HRESULT WINAPI ddraw_sample_Update(IDirectDrawStreamSample *iface,
|
|||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
if (flags & ~SSUPDATE_ASYNC)
|
||||
{
|
||||
FIXME("Unsupported flags %#x.\n", flags);
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
EnterCriticalSection(&sample->parent->cs);
|
||||
|
||||
if (sample->parent->state != State_Running)
|
||||
|
@ -1559,13 +1565,16 @@ static HRESULT WINAPI ddraw_sample_Update(IDirectDrawStreamSample *iface,
|
|||
LeaveCriticalSection(&sample->parent->cs);
|
||||
return MS_S_ENDOFSTREAM;
|
||||
}
|
||||
if (MS_S_PENDING == sample->update_hr)
|
||||
if (sample->busy)
|
||||
{
|
||||
LeaveCriticalSection(&sample->parent->cs);
|
||||
return MS_E_BUSY;
|
||||
}
|
||||
|
||||
sample->update_hr = MS_S_PENDING;
|
||||
sample->continuous_update = (flags & SSUPDATE_ASYNC) && (flags & SSUPDATE_CONTINUOUS);
|
||||
|
||||
sample->update_hr = MS_S_NOUPDATE;
|
||||
sample->busy = TRUE;
|
||||
list_add_tail(&sample->parent->update_queue, &sample->entry);
|
||||
WakeConditionVariable(&sample->parent->update_queued_cv);
|
||||
|
||||
|
@ -1575,7 +1584,7 @@ static HRESULT WINAPI ddraw_sample_Update(IDirectDrawStreamSample *iface,
|
|||
return MS_S_PENDING;
|
||||
}
|
||||
|
||||
while (sample->update_hr == MS_S_PENDING)
|
||||
while (sample->busy)
|
||||
SleepConditionVariableCS(&sample->update_cv, &sample->parent->cs, INFINITE);
|
||||
|
||||
LeaveCriticalSection(&sample->parent->cs);
|
||||
|
@ -1592,18 +1601,18 @@ static HRESULT WINAPI ddraw_sample_CompletionStatus(IDirectDrawStreamSample *ifa
|
|||
|
||||
EnterCriticalSection(&sample->parent->cs);
|
||||
|
||||
if (sample->update_hr == MS_S_PENDING)
|
||||
if (sample->busy)
|
||||
{
|
||||
if (flags & (COMPSTAT_NOUPDATEOK | COMPSTAT_ABORT))
|
||||
{
|
||||
sample->update_hr = MS_S_NOUPDATE;
|
||||
remove_queued_update(sample);
|
||||
}
|
||||
else if (flags & COMPSTAT_WAIT)
|
||||
{
|
||||
DWORD start_time = GetTickCount();
|
||||
DWORD elapsed = 0;
|
||||
while (sample->update_hr == MS_S_PENDING && elapsed < milliseconds)
|
||||
sample->continuous_update = FALSE;
|
||||
while (sample->busy && elapsed < milliseconds)
|
||||
{
|
||||
DWORD sleep_time = milliseconds - elapsed;
|
||||
if (!SleepConditionVariableCS(&sample->update_cv, &sample->parent->cs, sleep_time))
|
||||
|
@ -1613,7 +1622,7 @@ static HRESULT WINAPI ddraw_sample_CompletionStatus(IDirectDrawStreamSample *ifa
|
|||
}
|
||||
}
|
||||
|
||||
hr = sample->update_hr;
|
||||
hr = sample->busy ? MS_S_PENDING : sample->update_hr;
|
||||
|
||||
LeaveCriticalSection(&sample->parent->cs);
|
||||
|
||||
|
|
|
@ -7440,6 +7440,96 @@ static void test_ddrawstreamsample_update(void)
|
|||
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
for (i = 0; i < 5; ++i)
|
||||
memcpy((BYTE *)desc.lpSurface + i * desc.lPitch, initial_data, 12);
|
||||
hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
|
||||
|
||||
ammediastream_mem_input_pin = mem_input_pin;
|
||||
ammediastream_media_sample = media_sample;
|
||||
ammediastream_sleep_time = 100;
|
||||
ammediastream_expected_hr = S_OK;
|
||||
thread = CreateThread(NULL, 0, ammediastream_receive, NULL, 0, NULL);
|
||||
|
||||
hr = IDirectDrawStreamSample_Update(stream_sample, SSUPDATE_CONTINUOUS, NULL, NULL, 0);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(memcmp((BYTE *)desc.lpSurface + 0 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
|
||||
ok(memcmp((BYTE *)desc.lpSurface + 1 * desc.lPitch, &test_data[12], 12) == 0, "Sample data didn't match.\n");
|
||||
ok(memcmp((BYTE *)desc.lpSurface + 2 * desc.lPitch, &test_data[0], 12) == 0, "Sample data didn't match.\n");
|
||||
ok(memcmp((BYTE *)desc.lpSurface + 3 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
|
||||
ok(memcmp((BYTE *)desc.lpSurface + 4 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
|
||||
hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
|
||||
CloseHandle(thread);
|
||||
|
||||
ref = IMediaSample_Release(media_sample);
|
||||
ok(!ref, "Got outstanding refcount %d.\n", ref);
|
||||
|
||||
hr = IDirectDrawStreamSample_Update(stream_sample, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
|
||||
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
for (i = 0; i < 5; ++i)
|
||||
memcpy((BYTE *)desc.lpSurface + i * desc.lPitch, initial_data, 12);
|
||||
hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
|
||||
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ref = IMediaSample_Release(media_sample);
|
||||
ok(!ref, "Got outstanding refcount %d.\n", ref);
|
||||
|
||||
hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(memcmp((BYTE *)desc.lpSurface + 0 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
|
||||
ok(memcmp((BYTE *)desc.lpSurface + 1 * desc.lPitch, &test_data[12], 12) == 0, "Sample data didn't match.\n");
|
||||
ok(memcmp((BYTE *)desc.lpSurface + 2 * desc.lPitch, &test_data[0], 12) == 0, "Sample data didn't match.\n");
|
||||
ok(memcmp((BYTE *)desc.lpSurface + 3 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
|
||||
ok(memcmp((BYTE *)desc.lpSurface + 4 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
|
||||
hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
for (i = 0; i < 5; ++i)
|
||||
memcpy((BYTE *)desc.lpSurface + i * desc.lPitch, initial_data, 12);
|
||||
hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
|
||||
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ref = IMediaSample_Release(media_sample);
|
||||
ok(!ref, "Got outstanding refcount %d.\n", ref);
|
||||
|
||||
hr = IDirectDrawSurface_Lock(surface, NULL, &desc, 0, NULL);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ok(memcmp((BYTE *)desc.lpSurface + 0 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
|
||||
ok(memcmp((BYTE *)desc.lpSurface + 1 * desc.lPitch, &test_data[12], 12) == 0, "Sample data didn't match.\n");
|
||||
ok(memcmp((BYTE *)desc.lpSurface + 2 * desc.lPitch, &test_data[0], 12) == 0, "Sample data didn't match.\n");
|
||||
ok(memcmp((BYTE *)desc.lpSurface + 3 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
|
||||
ok(memcmp((BYTE *)desc.lpSurface + 4 * desc.lPitch, initial_data, 12) == 0, "Sample data didn't match.\n");
|
||||
hr = IDirectDrawSurface_Unlock(surface, desc.lpSurface);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IPin_EndOfStream(pin);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawStreamSample_Update(stream_sample, SSUPDATE_ASYNC, NULL, NULL, 0);
|
||||
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
|
||||
EXPECT_REF(stream_sample, 1);
|
||||
|
@ -7665,6 +7755,140 @@ static void test_ddrawstreamsample_completion_status(void)
|
|||
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
|
||||
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_NOUPDATEOK, 0);
|
||||
ok(hr == MS_S_NOUPDATE, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
|
||||
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_ABORT, 0);
|
||||
ok(hr == MS_S_NOUPDATE, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
|
||||
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
|
||||
ok(hr == MS_E_BUSY, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
|
||||
ok(hr == MS_E_BUSY, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawStreamSample_Update(stream_sample2, SSUPDATE_ASYNC, NULL, NULL, 0);
|
||||
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
|
||||
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
|
||||
|
||||
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
|
||||
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ref = IMediaSample_Release(media_sample);
|
||||
ok(!ref, "Got outstanding refcount %d.\n", ref);
|
||||
|
||||
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
|
||||
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample2, 0, 0);
|
||||
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
|
||||
|
||||
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
|
||||
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ref = IMediaSample_Release(media_sample);
|
||||
ok(!ref, "Got outstanding refcount %d.\n", ref);
|
||||
|
||||
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
|
||||
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample2, 0, 0);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_NOUPDATEOK, 0);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
|
||||
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IPin_BeginFlush(pin);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
|
||||
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IPin_EndFlush(pin);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
|
||||
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
|
||||
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
|
||||
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IPin_EndOfStream(pin);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
|
||||
ok(hr == MS_S_ENDOFSTREAM, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
|
||||
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, COMPSTAT_WAIT, 0);
|
||||
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
|
||||
|
||||
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
|
||||
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ref = IMediaSample_Release(media_sample);
|
||||
ok(!ref, "Got outstanding refcount %d.\n", ref);
|
||||
|
||||
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC | SSUPDATE_CONTINUOUS, NULL, NULL, 0);
|
||||
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
|
||||
|
||||
streamsample_sample = (IStreamSample *)stream_sample1;
|
||||
streamsample_flags = COMPSTAT_WAIT;
|
||||
streamsample_timeout = INFINITE;
|
||||
streamsample_expected_hr = S_OK;
|
||||
thread = CreateThread(NULL, 0, streamsample_completion_status, NULL, 0, NULL);
|
||||
ok(WaitForSingleObject(thread, 100) == WAIT_TIMEOUT, "CompletionStatus returned prematurely.\n");
|
||||
|
||||
media_sample = ammediastream_allocate_sample(&source, test_data, sizeof(test_data));
|
||||
hr = IMemInputPin_Receive(source.source.pMemInputPin, media_sample);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
ref = IMediaSample_Release(media_sample);
|
||||
ok(!ref, "Got outstanding refcount %d.\n", ref);
|
||||
|
||||
ok(!WaitForSingleObject(thread, 2000), "Wait timed out.\n");
|
||||
CloseHandle(thread);
|
||||
|
||||
hr = IDirectDrawStreamSample_CompletionStatus(stream_sample1, 0, 0);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_STOP);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
hr = IAMMultiMediaStream_SetState(mmstream, STREAMSTATE_RUN);
|
||||
ok(hr == S_OK, "Got hr %#x.\n", hr);
|
||||
|
||||
hr = IDirectDrawStreamSample_Update(stream_sample1, SSUPDATE_ASYNC, NULL, NULL, 0);
|
||||
ok(hr == MS_S_PENDING, "Got hr %#x.\n", hr);
|
||||
|
||||
|
|
Loading…
Reference in New Issue