evr/sample: Reset attributes, timestamps, and flags on ::Clear().
Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
600c818628
commit
35d7dc9040
|
@ -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)))
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue