Nikolay Sivov : evr/sample: Reset attributes, timestamps, and flags on ::Clear().
Alexandre Julliard
julliard at winehq.org
Mon Nov 16 15:28:57 CST 2020
Module: wine
Branch: master
Commit: 35d7dc9040698767e06552fd619798850b3bb433
URL: https://source.winehq.org/git/wine.git/?a=commit;h=35d7dc9040698767e06552fd619798850b3bb433
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Mon Nov 16 17:50:20 2020 +0300
evr/sample: Reset attributes, timestamps, and flags on ::Clear().
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
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);
More information about the wine-cvs
mailing list