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