Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/evr/sample.c | 74 ++++++++++++++++++++++++++++++++++---------- dlls/evr/tests/evr.c | 39 +++++++++++++++++++++++ 2 files changed, 96 insertions(+), 17 deletions(-)
diff --git a/dlls/evr/sample.c b/dlls/evr/sample.c index 7764ec945d2..aedf19b9fd4 100644 --- a/dlls/evr/sample.c +++ b/dlls/evr/sample.c @@ -61,6 +61,13 @@ struct surface_buffer ULONG length; };
+enum sample_prop_flags +{ + SAMPLE_PROP_HAS_DURATION = 1 << 0, + SAMPLE_PROP_HAS_TIMESTAMP = 1 << 1, + SAMPLE_PROP_HAS_DESIRED_PROPS = 1 << 2, +}; + struct video_sample { IMFSample IMFSample_iface; @@ -73,9 +80,12 @@ struct video_sample IMFAsyncResult *tracked_result; LONG tracked_refcount;
- LONGLONG desired_time; + LONGLONG timestamp; + LONGLONG duration; + LONGLONG desired_timestamp; LONGLONG desired_duration; - BOOL desired_set; + unsigned int flags; + CRITICAL_SECTION cs; };
static struct video_sample *impl_from_IMFSample(IMFSample *iface) @@ -931,6 +941,7 @@ static ULONG WINAPI video_sample_Release(IMFSample *iface) video_sample_stop_tracking_thread(); if (sample->sample) IMFSample_Release(sample->sample); + DeleteCriticalSection(&sample->cs); heap_free(sample); }
@@ -1229,10 +1240,18 @@ static HRESULT WINAPI video_sample_SetSampleFlags(IMFSample *iface, DWORD flags) static HRESULT WINAPI video_sample_GetSampleTime(IMFSample *iface, LONGLONG *timestamp) { struct video_sample *sample = impl_from_IMFSample(iface); + HRESULT hr = S_OK;
TRACE("%p, %p.\n", iface, timestamp);
- return IMFSample_GetSampleTime(sample->sample, timestamp); + EnterCriticalSection(&sample->cs); + if (sample->flags & SAMPLE_PROP_HAS_TIMESTAMP) + *timestamp = sample->timestamp; + else + hr = MF_E_NO_SAMPLE_TIMESTAMP; + LeaveCriticalSection(&sample->cs); + + return hr; }
static HRESULT WINAPI video_sample_SetSampleTime(IMFSample *iface, LONGLONG timestamp) @@ -1241,16 +1260,29 @@ static HRESULT WINAPI video_sample_SetSampleTime(IMFSample *iface, LONGLONG time
TRACE("%p, %s.\n", iface, debugstr_time(timestamp));
- return IMFSample_SetSampleTime(sample->sample, timestamp); + EnterCriticalSection(&sample->cs); + sample->timestamp = timestamp; + sample->flags |= SAMPLE_PROP_HAS_TIMESTAMP; + LeaveCriticalSection(&sample->cs); + + return S_OK; }
static HRESULT WINAPI video_sample_GetSampleDuration(IMFSample *iface, LONGLONG *duration) { struct video_sample *sample = impl_from_IMFSample(iface); + HRESULT hr = S_OK;
TRACE("%p, %p.\n", iface, duration);
- return IMFSample_GetSampleDuration(sample->sample, duration); + EnterCriticalSection(&sample->cs); + if (sample->flags & SAMPLE_PROP_HAS_DURATION) + *duration = sample->duration; + else + hr = MF_E_NO_SAMPLE_DURATION; + LeaveCriticalSection(&sample->cs); + + return hr; }
static HRESULT WINAPI video_sample_SetSampleDuration(IMFSample *iface, LONGLONG duration) @@ -1259,7 +1291,12 @@ static HRESULT WINAPI video_sample_SetSampleDuration(IMFSample *iface, LONGLONG
TRACE("%p, %s.\n", iface, debugstr_time(duration));
- return IMFSample_SetSampleDuration(sample->sample, duration); + EnterCriticalSection(&sample->cs); + sample->duration = duration; + sample->flags |= SAMPLE_PROP_HAS_DURATION; + LeaveCriticalSection(&sample->cs); + + return S_OK; }
static HRESULT WINAPI video_sample_GetBufferCount(IMFSample *iface, DWORD *count) @@ -1468,15 +1505,15 @@ static HRESULT WINAPI desired_video_sample_GetDesiredSampleTimeAndDuration(IMFDe if (!sample_time || !sample_duration) return E_POINTER;
- IMFSample_LockStore(sample->sample); - if (sample->desired_set) + EnterCriticalSection(&sample->cs); + if (sample->flags & SAMPLE_PROP_HAS_DESIRED_PROPS) { - *sample_time = sample->desired_time; + *sample_time = sample->desired_timestamp; *sample_duration = sample->desired_duration; } else hr = MF_E_NOT_AVAILABLE; - IMFSample_UnlockStore(sample->sample); + LeaveCriticalSection(&sample->cs);
return hr; } @@ -1488,11 +1525,11 @@ static void WINAPI desired_video_sample_SetDesiredSampleTimeAndDuration(IMFDesir
TRACE("%p, %s, %s.\n", iface, debugstr_time(sample_time), debugstr_time(sample_duration));
- IMFSample_LockStore(sample->sample); - sample->desired_set = TRUE; - sample->desired_time = sample_time; + EnterCriticalSection(&sample->cs); + sample->flags |= SAMPLE_PROP_HAS_DESIRED_PROPS; + sample->desired_timestamp = sample_time; sample->desired_duration = sample_duration; - IMFSample_UnlockStore(sample->sample); + LeaveCriticalSection(&sample->cs); }
static void WINAPI desired_video_sample_Clear(IMFDesiredSample *iface) @@ -1501,9 +1538,11 @@ static void WINAPI desired_video_sample_Clear(IMFDesiredSample *iface)
TRACE("%p.\n", iface);
- IMFSample_LockStore(sample->sample); - sample->desired_set = FALSE; - IMFSample_UnlockStore(sample->sample); + EnterCriticalSection(&sample->cs); + sample->flags = 0; + IMFSample_SetSampleFlags(sample->sample, 0); + IMFSample_DeleteAllItems(sample->sample); + LeaveCriticalSection(&sample->cs); }
static const IMFDesiredSampleVtbl desired_video_sample_vtbl = @@ -1693,6 +1732,7 @@ HRESULT WINAPI MFCreateVideoSampleFromSurface(IUnknown *surface, IMFSample **sam object->IMFTrackedSample_iface.lpVtbl = &tracked_video_sample_vtbl; object->IMFDesiredSample_iface.lpVtbl = &desired_video_sample_vtbl; object->refcount = 1; + InitializeCriticalSection(&object->cs);
if (FAILED(hr = MFCreateSample(&object->sample))) { diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c index 882d61b9d37..f1831b58f89 100644 --- a/dlls/evr/tests/evr.c +++ b/dlls/evr/tests/evr.c @@ -790,6 +790,45 @@ static void test_surface_sample(void) ok(hr == S_OK, "Unexpected hr %#x.\n", hr); ok(!count, "Unexpected attribute count %u.\n", count);
+ /* Attributes are cleared. */ + hr = IMFSample_SetUnknown(sample, &MFSampleExtension_Token, NULL); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFSample_GetCount(sample, &count); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(count == 1, "Unexpected attribute count %u.\n", count); + + hr = IMFSample_SetSampleTime(sample, 0); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFSample_GetSampleTime(sample, &time1); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFSample_SetSampleDuration(sample, 0); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFSample_GetSampleDuration(sample, &duration); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFSample_SetSampleFlags(sample, 0x1); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + IMFDesiredSample_Clear(desired_sample); + + hr = IMFSample_GetCount(sample, &count); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(!count, "Unexpected attribute count %u.\n", count); + + hr = IMFSample_GetSampleTime(sample, &time1); + ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#x.\n", hr); + + hr = IMFSample_GetSampleDuration(sample, &duration); + ok(hr == MF_E_NO_SAMPLE_DURATION, "Unexpected hr %#x.\n", hr); + + hr = IMFSample_GetSampleFlags(sample, &flags); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(flags == 0, "Unexpected flags %#x.\n", flags); + IMFDesiredSample_Release(desired_sample);
hr = IMFSample_GetCount(sample, &count);