From 23237173b9ddb26fe26eb5b11b658dc78709f51e Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Mon, 18 Mar 2019 13:00:59 +0300 Subject: [PATCH] mfplat: Add sample timestamp and duration methods. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/mfplat/buffer.c | 63 ++++++++++++++++++++++++++++++++------ dlls/mfplat/tests/mfplat.c | 25 +++++++++++++-- 2 files changed, 76 insertions(+), 12 deletions(-) diff --git a/dlls/mfplat/buffer.c b/dlls/mfplat/buffer.c index b07ec875f96..de08b1b5bef 100644 --- a/dlls/mfplat/buffer.c +++ b/dlls/mfplat/buffer.c @@ -34,6 +34,12 @@ struct memory_buffer DWORD current_length; }; +enum sample_prop_flags +{ + SAMPLE_PROP_HAS_DURATION = 1 << 0, + SAMPLE_PROP_HAS_TIMESTAMP = 1 << 1, +}; + struct sample { struct attributes attributes; @@ -44,6 +50,9 @@ struct sample size_t capacity; DWORD flags; CRITICAL_SECTION cs; + DWORD prop_flags; + LONGLONG duration; + LONGLONG timestamp; }; static inline struct memory_buffer *impl_from_IMFMediaBuffer(IMFMediaBuffer *iface) @@ -487,32 +496,66 @@ static HRESULT WINAPI sample_SetSampleFlags(IMFSample *iface, DWORD flags) return S_OK; } -static HRESULT WINAPI sample_GetSampleTime(IMFSample *iface, LONGLONG *sampletime) +static HRESULT WINAPI sample_GetSampleTime(IMFSample *iface, LONGLONG *timestamp) { - FIXME("%p, %p.\n", iface, sampletime); + struct sample *sample = impl_from_IMFSample(iface); + HRESULT hr = S_OK; - return E_NOTIMPL; + TRACE("%p, %p.\n", iface, timestamp); + + EnterCriticalSection(&sample->cs); + if (sample->prop_flags & SAMPLE_PROP_HAS_TIMESTAMP) + *timestamp = sample->timestamp; + else + hr = MF_E_NO_SAMPLE_TIMESTAMP; + LeaveCriticalSection(&sample->cs); + + return hr; } -static HRESULT WINAPI sample_SetSampleTime(IMFSample *iface, LONGLONG sampletime) +static HRESULT WINAPI sample_SetSampleTime(IMFSample *iface, LONGLONG timestamp) { - FIXME("%p, %s.\n", iface, wine_dbgstr_longlong(sampletime)); + struct sample *sample = impl_from_IMFSample(iface); - return E_NOTIMPL; + TRACE("%p, %s.\n", iface, wine_dbgstr_longlong(timestamp)); + + EnterCriticalSection(&sample->cs); + sample->timestamp = timestamp; + sample->prop_flags |= SAMPLE_PROP_HAS_TIMESTAMP; + LeaveCriticalSection(&sample->cs); + + return S_OK; } static HRESULT WINAPI sample_GetSampleDuration(IMFSample *iface, LONGLONG *duration) { - FIXME("%p, %p.\n", iface, duration); + struct sample *sample = impl_from_IMFSample(iface); + HRESULT hr = S_OK; - return E_NOTIMPL; + TRACE("%p, %p.\n", iface, duration); + + EnterCriticalSection(&sample->cs); + if (sample->prop_flags & SAMPLE_PROP_HAS_DURATION) + *duration = sample->duration; + else + hr = MF_E_NO_SAMPLE_DURATION; + LeaveCriticalSection(&sample->cs); + + return hr; } static HRESULT WINAPI sample_SetSampleDuration(IMFSample *iface, LONGLONG duration) { - FIXME("%p, %s.\n", iface, wine_dbgstr_longlong(duration)); + struct sample *sample = impl_from_IMFSample(iface); - return E_NOTIMPL; + TRACE("%p, %s.\n", iface, wine_dbgstr_longlong(duration)); + + EnterCriticalSection(&sample->cs); + sample->duration = duration; + sample->prop_flags |= SAMPLE_PROP_HAS_DURATION; + LeaveCriticalSection(&sample->cs); + + return S_OK; } static HRESULT WINAPI sample_GetBufferCount(IMFSample *iface, DWORD *count) diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 31b6ba186c0..ba9e8c3455c 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -1280,6 +1280,7 @@ static void test_sample(void) { IMFMediaBuffer *buffer, *buffer2; DWORD count, flags, length; + IMFAttributes *attributes; IMFSample *sample; LONGLONG time; HRESULT hr; @@ -1287,6 +1288,11 @@ static void test_sample(void) hr = MFCreateSample( &sample ); ok(hr == S_OK, "got 0x%08x\n", hr); + hr = IMFSample_QueryInterface(sample, &IID_IMFAttributes, (void **)&attributes); + ok(hr == S_OK, "Failed to get attributes interface, hr %#x.\n", hr); + + CHECK_ATTR_COUNT(attributes, 0); + hr = IMFSample_GetBufferCount(sample, NULL); ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); @@ -1305,11 +1311,9 @@ static void test_sample(void) ok(flags == 0x123, "Unexpected flags %#x.\n", flags); hr = IMFSample_GetSampleTime(sample, &time); -todo_wine ok(hr == MF_E_NO_SAMPLE_TIMESTAMP, "Unexpected hr %#x.\n", hr); hr = IMFSample_GetSampleDuration(sample, &time); -todo_wine ok(hr == MF_E_NO_SAMPLE_DURATION, "Unexpected hr %#x.\n", hr); hr = IMFSample_GetBufferByIndex(sample, 0, &buffer); @@ -1363,6 +1367,23 @@ todo_wine IMFMediaBuffer_Release(buffer); + /* Duration */ + hr = IMFSample_SetSampleDuration(sample, 10); + ok(hr == S_OK, "Failed to set duration, hr %#x.\n", hr); + CHECK_ATTR_COUNT(attributes, 0); + hr = IMFSample_GetSampleDuration(sample, &time); + ok(hr == S_OK, "Failed to get sample duration, hr %#x.\n", hr); + ok(time == 10, "Unexpected duration.\n"); + + /* Timestamp */ + hr = IMFSample_SetSampleTime(sample, 1); + ok(hr == S_OK, "Failed to set timestamp, hr %#x.\n", hr); + CHECK_ATTR_COUNT(attributes, 0); + hr = IMFSample_GetSampleTime(sample, &time); + ok(hr == S_OK, "Failed to get sample time, hr %#x.\n", hr); + ok(time == 1, "Unexpected timestamp.\n"); + + IMFAttributes_Release(attributes); IMFSample_Release(sample); }