Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/mf.spec | 2 +- dlls/mf/session.c | 381 +++++++++++++++++++++++++++++++++++++++++++++ dlls/mf/tests/mf.c | 63 ++++++++ include/mferror.h | 2 + include/mfidl.idl | 58 ++++++- 5 files changed, 504 insertions(+), 2 deletions(-)
diff --git a/dlls/mf/mf.spec b/dlls/mf/mf.spec index 7ec8e57c1f..2d02ef8fec 100644 --- a/dlls/mf/mf.spec +++ b/dlls/mf/mf.spec @@ -45,7 +45,7 @@ @ stub MFCreatePMPHost @ stub MFCreatePMPMediaSession @ stub MFCreatePMPServer -@ stub MFCreatePresentationClock +@ stdcall MFCreatePresentationClock(ptr) @ stub MFCreatePresentationDescriptorFromASFProfile @ stub MFCreateProxyLocator @ stub MFCreateRemoteDesktopPlugin diff --git a/dlls/mf/session.c b/dlls/mf/session.c index b576a0f184..2961abe879 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -25,6 +25,7 @@ #include "winbase.h" #include "mfidl.h" #include "mfapi.h" +#include "mferror.h"
#include "wine/debug.h" #include "wine/heap.h" @@ -38,11 +39,43 @@ struct media_session IMFMediaEventQueue *event_queue; };
+struct presentation_clock +{ + IMFPresentationClock IMFPresentationClock_iface; + IMFRateControl IMFRateControl_iface; + IMFTimer IMFTimer_iface; + IMFShutdown IMFShutdown_iface; + LONG refcount; + IMFPresentationTimeSource *time_source; + MFCLOCK_STATE state; + CRITICAL_SECTION cs; +}; + static inline struct media_session *impl_from_IMFMediaSession(IMFMediaSession *iface) { return CONTAINING_RECORD(iface, struct media_session, IMFMediaSession_iface); }
+static struct presentation_clock *impl_from_IMFPresentationClock(IMFPresentationClock *iface) +{ + return CONTAINING_RECORD(iface, struct presentation_clock, IMFPresentationClock_iface); +} + +static struct presentation_clock *impl_from_IMFRateControl(IMFRateControl *iface) +{ + return CONTAINING_RECORD(iface, struct presentation_clock, IMFRateControl_iface); +} + +static struct presentation_clock *impl_from_IMFTimer(IMFTimer *iface) +{ + return CONTAINING_RECORD(iface, struct presentation_clock, IMFTimer_iface); +} + +static struct presentation_clock *impl_from_IMFShutdown(IMFShutdown *iface) +{ + return CONTAINING_RECORD(iface, struct presentation_clock, IMFShutdown_iface); +} + static HRESULT WINAPI mfsession_QueryInterface(IMFMediaSession *iface, REFIID riid, void **out) { struct media_session *session = impl_from_IMFMediaSession(iface); @@ -251,3 +284,351 @@ HRESULT WINAPI MFCreateMediaSession(IMFAttributes *config, IMFMediaSession **ses
return S_OK; } + +static HRESULT WINAPI present_clock_QueryInterface(IMFPresentationClock *iface, REFIID riid, void **out) +{ + struct presentation_clock *clock = impl_from_IMFPresentationClock(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out); + + if (IsEqualIID(riid, &IID_IMFPresentationClock) || + IsEqualIID(riid, &IID_IMFClock) || + IsEqualIID(riid, &IID_IUnknown)) + { + *out = &clock->IMFPresentationClock_iface; + } + else if (IsEqualIID(riid, &IID_IMFRateControl)) + { + *out = &clock->IMFRateControl_iface; + } + else if (IsEqualIID(riid, &IID_IMFTimer)) + { + *out = &clock->IMFTimer_iface; + } + else if (IsEqualIID(riid, &IID_IMFShutdown)) + { + *out = &clock->IMFShutdown_iface; + } + else + { + WARN("Unsupported %s.\n", debugstr_guid(riid)); + *out = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown *)*out); + return S_OK; +} + +static ULONG WINAPI present_clock_AddRef(IMFPresentationClock *iface) +{ + struct presentation_clock *clock = impl_from_IMFPresentationClock(iface); + ULONG refcount = InterlockedIncrement(&clock->refcount); + + TRACE("%p, refcount %u.\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI present_clock_Release(IMFPresentationClock *iface) +{ + struct presentation_clock *clock = impl_from_IMFPresentationClock(iface); + ULONG refcount = InterlockedDecrement(&clock->refcount); + + TRACE("%p, refcount %u.\n", iface, refcount); + + if (!refcount) + { + if (clock->time_source) + IMFPresentationTimeSource_Release(clock->time_source); + DeleteCriticalSection(&clock->cs); + heap_free(clock); + } + + return refcount; +} + +static HRESULT WINAPI present_clock_GetClockCharacteristics(IMFPresentationClock *iface, DWORD *flags) +{ + FIXME("%p, %p.\n", iface, flags); + + return E_NOTIMPL; +} + +static HRESULT WINAPI present_clock_GetCorrelatedTime(IMFPresentationClock *iface, DWORD reserved, + LONGLONG *clock_time, MFTIME *system_time) +{ + FIXME("%p, %#x, %p, %p.\n", iface, reserved, clock_time, system_time); + + return E_NOTIMPL; +} + +static HRESULT WINAPI present_clock_GetContinuityKey(IMFPresentationClock *iface, DWORD *key) +{ + TRACE("%p, %p.\n", iface, key); + + *key = 0; + + return S_OK; +} + +static HRESULT WINAPI present_clock_GetState(IMFPresentationClock *iface, DWORD reserved, MFCLOCK_STATE *state) +{ + struct presentation_clock *clock = impl_from_IMFPresentationClock(iface); + + TRACE("%p, %#x, %p.\n", iface, reserved, state); + + EnterCriticalSection(&clock->cs); + *state = clock->state; + LeaveCriticalSection(&clock->cs); + + return S_OK; +} + +static HRESULT WINAPI present_clock_GetProperties(IMFPresentationClock *iface, MFCLOCK_PROPERTIES *props) +{ + FIXME("%p, %p.\n", iface, props); + + return E_NOTIMPL; +} + +static HRESULT WINAPI present_clock_SetTimeSource(IMFPresentationClock *iface, + IMFPresentationTimeSource *time_source) +{ + FIXME("%p, %p.\n", iface, time_source); + + return E_NOTIMPL; +} + +static HRESULT WINAPI present_clock_GetTimeSource(IMFPresentationClock *iface, + IMFPresentationTimeSource **time_source) +{ + struct presentation_clock *clock = impl_from_IMFPresentationClock(iface); + HRESULT hr = S_OK; + + TRACE("%p, %p.\n", iface, time_source); + + EnterCriticalSection(&clock->cs); + if (clock->time_source) + { + *time_source = clock->time_source; + IMFPresentationTimeSource_AddRef(*time_source); + } + else + hr = MF_E_CLOCK_NO_TIME_SOURCE; + LeaveCriticalSection(&clock->cs); + + return hr; +} + +static HRESULT WINAPI present_clock_GetTime(IMFPresentationClock *iface, MFTIME *time) +{ + FIXME("%p, %p.\n", iface, time); + + return E_NOTIMPL; +} + +static HRESULT WINAPI present_clock_AddClockStateSink(IMFPresentationClock *iface, IMFClockStateSink *state_sink) +{ + FIXME("%p, %p.\n", iface, state_sink); + + return E_NOTIMPL; +} + +static HRESULT WINAPI present_clock_RemoveClockStateSink(IMFPresentationClock *iface, + IMFClockStateSink *state_sink) +{ + FIXME("%p, %p.\n", iface, state_sink); + + return E_NOTIMPL; +} + +static HRESULT WINAPI present_clock_Start(IMFPresentationClock *iface, LONGLONG start_offset) +{ + FIXME("%p, %s.\n", iface, wine_dbgstr_longlong(start_offset)); + + return E_NOTIMPL; +} + +static HRESULT WINAPI present_clock_Stop(IMFPresentationClock *iface) +{ + FIXME("%p.\n", iface); + + return E_NOTIMPL; +} + +static HRESULT WINAPI present_clock_Pause(IMFPresentationClock *iface) +{ + FIXME("%p.\n", iface); + + return E_NOTIMPL; +} + +static const IMFPresentationClockVtbl presentationclockvtbl = +{ + present_clock_QueryInterface, + present_clock_AddRef, + present_clock_Release, + present_clock_GetClockCharacteristics, + present_clock_GetCorrelatedTime, + present_clock_GetContinuityKey, + present_clock_GetState, + present_clock_GetProperties, + present_clock_SetTimeSource, + present_clock_GetTimeSource, + present_clock_GetTime, + present_clock_AddClockStateSink, + present_clock_RemoveClockStateSink, + present_clock_Start, + present_clock_Stop, + present_clock_Pause, +}; + +static HRESULT WINAPI present_clock_rate_control_QueryInterface(IMFRateControl *iface, REFIID riid, void **out) +{ + struct presentation_clock *clock = impl_from_IMFRateControl(iface); + return IMFPresentationClock_QueryInterface(&clock->IMFPresentationClock_iface, riid, out); +} + +static ULONG WINAPI present_clock_rate_control_AddRef(IMFRateControl *iface) +{ + struct presentation_clock *clock = impl_from_IMFRateControl(iface); + return IMFPresentationClock_AddRef(&clock->IMFPresentationClock_iface); +} + +static ULONG WINAPI present_clock_rate_control_Release(IMFRateControl *iface) +{ + struct presentation_clock *clock = impl_from_IMFRateControl(iface); + return IMFPresentationClock_Release(&clock->IMFPresentationClock_iface); +} + +static HRESULT WINAPI present_clock_rate_SetRate(IMFRateControl *iface, BOOL thin, float rate) +{ + FIXME("%p, %d, %f.\n", iface, thin, rate); + + return E_NOTIMPL; +} + +static HRESULT WINAPI present_clock_rate_GetRate(IMFRateControl *iface, BOOL *thin, float *rate) +{ + FIXME("%p, %p, %p.\n", iface, thin, rate); + + return E_NOTIMPL; +} + +static const IMFRateControlVtbl presentclockratecontrolvtbl = +{ + present_clock_rate_control_QueryInterface, + present_clock_rate_control_AddRef, + present_clock_rate_control_Release, + present_clock_rate_SetRate, + present_clock_rate_GetRate, +}; + +static HRESULT WINAPI present_clock_timer_QueryInterface(IMFTimer *iface, REFIID riid, void **out) +{ + struct presentation_clock *clock = impl_from_IMFTimer(iface); + return IMFPresentationClock_QueryInterface(&clock->IMFPresentationClock_iface, riid, out); +} + +static ULONG WINAPI present_clock_timer_AddRef(IMFTimer *iface) +{ + struct presentation_clock *clock = impl_from_IMFTimer(iface); + return IMFPresentationClock_AddRef(&clock->IMFPresentationClock_iface); +} + +static ULONG WINAPI present_clock_timer_Release(IMFTimer *iface) +{ + struct presentation_clock *clock = impl_from_IMFTimer(iface); + return IMFPresentationClock_Release(&clock->IMFPresentationClock_iface); +} + +static HRESULT WINAPI present_clock_timer_SetTimer(IMFTimer *iface, DWORD flags, LONGLONG time, + IMFAsyncCallback *callback, IUnknown *state, IUnknown **cancel_key) +{ + FIXME("%p, %#x, %s, %p, %p, %p.\n", iface, flags, wine_dbgstr_longlong(time), callback, state, cancel_key); + + return E_NOTIMPL; +} + +static HRESULT WINAPI present_clock_timer_CancelTimer(IMFTimer *iface, IUnknown *cancel_key) +{ + FIXME("%p, %p.\n", iface, cancel_key); + + return E_NOTIMPL; +} + +static const IMFTimerVtbl presentclocktimervtbl = +{ + present_clock_timer_QueryInterface, + present_clock_timer_AddRef, + present_clock_timer_Release, + present_clock_timer_SetTimer, + present_clock_timer_CancelTimer, +}; + +static HRESULT WINAPI present_clock_shutdown_QueryInterface(IMFShutdown *iface, REFIID riid, void **out) +{ + struct presentation_clock *clock = impl_from_IMFShutdown(iface); + return IMFPresentationClock_QueryInterface(&clock->IMFPresentationClock_iface, riid, out); +} + +static ULONG WINAPI present_clock_shutdown_AddRef(IMFShutdown *iface) +{ + struct presentation_clock *clock = impl_from_IMFShutdown(iface); + return IMFPresentationClock_AddRef(&clock->IMFPresentationClock_iface); +} + +static ULONG WINAPI present_clock_shutdown_Release(IMFShutdown *iface) +{ + struct presentation_clock *clock = impl_from_IMFShutdown(iface); + return IMFPresentationClock_Release(&clock->IMFPresentationClock_iface); +} + +static HRESULT WINAPI present_clock_shutdown_Shutdown(IMFShutdown *iface) +{ + FIXME("%p.\n", iface); + + return E_NOTIMPL; +} + +static HRESULT WINAPI present_clock_shutdown_GetShutdownStatus(IMFShutdown *iface, MFSHUTDOWN_STATUS *status) +{ + FIXME("%p, %p.\n", iface, status); + + return E_NOTIMPL; +} + +static const IMFShutdownVtbl presentclockshutdownvtbl = +{ + present_clock_shutdown_QueryInterface, + present_clock_shutdown_AddRef, + present_clock_shutdown_Release, + present_clock_shutdown_Shutdown, + present_clock_shutdown_GetShutdownStatus, +}; + +/*********************************************************************** + * MFCreatePresentationClock (mf.@) + */ +HRESULT WINAPI MFCreatePresentationClock(IMFPresentationClock **clock) +{ + struct presentation_clock *object; + + TRACE("%p.\n", clock); + + object = heap_alloc_zero(sizeof(*object)); + if (!object) + return E_OUTOFMEMORY; + + object->IMFPresentationClock_iface.lpVtbl = &presentationclockvtbl; + object->IMFRateControl_iface.lpVtbl = &presentclockratecontrolvtbl; + object->IMFTimer_iface.lpVtbl = &presentclocktimervtbl; + object->IMFShutdown_iface.lpVtbl = &presentclockshutdownvtbl; + object->refcount = 1; + InitializeCriticalSection(&object->cs); + + *clock = &object->IMFPresentationClock_iface; + + return S_OK; +} diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 2d005547b7..9fa0bda839 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -735,6 +735,68 @@ static void test_MFShutdownObject(void) ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr); }
+static void test_presentation_clock(void) +{ + IMFPresentationTimeSource *time_source; + IMFRateControl *rate_control; + IMFPresentationClock *clock; + MFCLOCK_PROPERTIES props; + IMFShutdown *shutdown; + LONGLONG clock_time; + MFCLOCK_STATE state; + IMFTimer *timer; + MFTIME systime; + DWORD value; + HRESULT hr; + + hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); + ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr); + + hr = MFCreatePresentationClock(&clock); + ok(hr == S_OK, "Failed to create presentation clock, hr %#x.\n", hr); + + hr = IMFPresentationClock_GetTimeSource(clock, &time_source); + ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr); + + hr = IMFPresentationClock_GetClockCharacteristics(clock, &value); +todo_wine + ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr); + + value = 1; + hr = IMFPresentationClock_GetContinuityKey(clock, &value); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(value == 0, "Unexpected value %u.\n", value); + + hr = IMFPresentationClock_GetProperties(clock, &props); +todo_wine + ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr); + + hr = IMFPresentationClock_GetState(clock, 0, &state); + ok(hr == S_OK, "Failed to get state, hr %#x.\n", hr); + ok(state == MFCLOCK_STATE_INVALID, "Unexpected state %d.\n", state); + + hr = IMFPresentationClock_GetCorrelatedTime(clock, 0, &clock_time, &systime); +todo_wine + ok(hr == MF_E_CLOCK_NO_TIME_SOURCE, "Unexpected hr %#x.\n", hr); + + hr = IMFPresentationClock_QueryInterface(clock, &IID_IMFRateControl, (void **)&rate_control); + ok(hr == S_OK, "Failed to get rate control interface, hr %#x.\n", hr); + IMFRateControl_Release(rate_control); + + hr = IMFPresentationClock_QueryInterface(clock, &IID_IMFTimer, (void **)&timer); + ok(hr == S_OK, "Failed to get timer interface, hr %#x.\n", hr); + IMFTimer_Release(timer); + + hr = IMFPresentationClock_QueryInterface(clock, &IID_IMFShutdown, (void **)&shutdown); + ok(hr == S_OK, "Failed to get shutdown interface, hr %#x.\n", hr); + IMFShutdown_Release(shutdown); + + IMFPresentationClock_Release(clock); + + hr = MFShutdown(); + ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr); +} + START_TEST(mf) { test_topology(); @@ -743,4 +805,5 @@ START_TEST(mf) test_MFCreateSequencerSource(); test_media_session(); test_MFShutdownObject(); + test_presentation_clock(); } diff --git a/include/mferror.h b/include/mferror.h index 54f09fefdc..be35e6e20f 100644 --- a/include/mferror.h +++ b/include/mferror.h @@ -82,4 +82,6 @@ #define MF_E_TOPO_MISSING_SOURCE _HRESULT_TYPEDEF_(0xc00d521a) #define MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED _HRESULT_TYPEDEF_(0xc00d521b)
+#define MF_E_CLOCK_NO_TIME_SOURCE _HRESULT_TYPEDEF_(0xc00d9c41) + #endif /* __WINE_MFERROR_H */ diff --git a/include/mfidl.idl b/include/mfidl.idl index be8795c854..48d7c8e501 100644 --- a/include/mfidl.idl +++ b/include/mfidl.idl @@ -70,6 +70,37 @@ interface IMFClock : IUnknown HRESULT GetProperties([out] MFCLOCK_PROPERTIES *props); }
+[ + object, + uuid(88ddcd21-03c3-4275-91ed-55ee3929328f) +] +interface IMFRateControl : IUnknown +{ + HRESULT SetRate( + [in] BOOL thin, + [in] float rate); + HRESULT GetRate( + [in, out, unique] BOOL *thin, + [in, out, unique] float *rate); +} + +[ + object, + uuid(e56e4cbd-8f70-49d8-a0f8-edb3d6ab9bf2), + local +] +interface IMFTimer : IUnknown +{ + HRESULT SetTimer( + [in] DWORD flags, + [in] LONGLONG time, + [in] IMFAsyncCallback *callback, + [in] IUnknown *state, + [out] IUnknown **key); + HRESULT CancelTimer( + [in] IUnknown *key); +} + [ object, uuid(83cf873a-f6da-4bc8-823f-bacfd55dc430), @@ -319,6 +350,7 @@ interface IMFSequencerSource : IUnknown cpp_quote("HRESULT WINAPI MFCreateMediaSession(IMFAttributes *config, IMFMediaSession **session);") cpp_quote("HRESULT WINAPI MFCreateMFByteStreamOnStream(IStream *stream, IMFByteStream **bytestream);" ) cpp_quote("HRESULT WINAPI MFCreateMFByteStreamOnStreamEx(IUnknown *stream, IMFByteStream **bytestream);") +cpp_quote("HRESULT WINAPI MFCreatePresentationClock(IMFPresentationClock **clock);") cpp_quote("HRESULT WINAPI MFCreateSequencerSource(IUnknown *reserved, IMFSequencerSource **seq_source);" ) cpp_quote("HRESULT WINAPI MFCreateSourceResolver(IMFSourceResolver **resolver);") cpp_quote("HRESULT WINAPI MFCreateStreamDescriptor(DWORD identifier, DWORD cMediaTypes,") @@ -360,7 +392,31 @@ interface IMFMediaSource : IMFMediaEventGenerator }
interface IMFStreamSink; -interface IMFPresentationClock; + +[ + object, + uuid(7ff12cce-f76f-41c2-863b-1666c8e5e139) +] +interface IMFPresentationTimeSource : IMFClock +{ + HRESULT GetUnderlyingClock([out] IMFClock **clock); +} + +[ + object, + uuid(868ce85c-8ea9-4f55-ab82-b009a910a805) +] +interface IMFPresentationClock : IMFClock +{ + HRESULT SetTimeSource([in] IMFPresentationTimeSource *time_source); + HRESULT GetTimeSource([out] IMFPresentationTimeSource **time_source); + HRESULT GetTime([out] MFTIME *time); + HRESULT AddClockStateSink([in] IMFClockStateSink *state_sink); + HRESULT RemoveClockStateSink([in] IMFClockStateSink *state_sink); + HRESULT Start([in] LONGLONG start_offset); + HRESULT Stop(); + HRESULT Pause(); +}
[ object,
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/mediatype.c | 463 +++++++++++++++++++++++++++++++++++++ dlls/mfplat/mfplat.spec | 2 +- dlls/mfplat/tests/mfplat.c | 76 ++++++ include/mfidl.idl | 2 + 4 files changed, 542 insertions(+), 1 deletion(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index a473c755d9..195ab38da5 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -43,6 +43,23 @@ struct stream_desc CRITICAL_SECTION cs; };
+struct presentation_desc_entry +{ + IMFStreamDescriptor *descriptor; + BOOL selected; +}; + +struct presentation_desc +{ + struct attributes attributes; + IMFPresentationDescriptor IMFPresentationDescriptor_iface; + struct presentation_desc_entry *descriptors; + unsigned int count; + CRITICAL_SECTION cs; +}; + +static HRESULT presentation_descriptor_init(struct presentation_desc *object, DWORD count); + static inline struct media_type *impl_from_IMFMediaType(IMFMediaType *iface) { return CONTAINING_RECORD(iface, struct media_type, IMFMediaType_iface); @@ -58,6 +75,11 @@ static struct stream_desc *impl_from_IMFMediaTypeHandler(IMFMediaTypeHandler *if return CONTAINING_RECORD(iface, struct stream_desc, IMFMediaTypeHandler_iface); }
+static struct presentation_desc *impl_from_IMFPresentationDescriptor(IMFPresentationDescriptor *iface) +{ + return CONTAINING_RECORD(iface, struct presentation_desc, IMFPresentationDescriptor_iface); +} + static HRESULT WINAPI mediatype_QueryInterface(IMFMediaType *iface, REFIID riid, void **out) { TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out); @@ -857,3 +879,444 @@ HRESULT WINAPI MFCreateStreamDescriptor(DWORD identifier, DWORD count,
return S_OK; } + +static HRESULT WINAPI presentation_descriptor_QueryInterface(IMFPresentationDescriptor *iface, REFIID riid, void **out) +{ + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out); + + if (IsEqualIID(riid, &IID_IMFPresentationDescriptor) || + IsEqualIID(riid, &IID_IMFAttributes) || + IsEqualIID(riid, &IID_IUnknown)) + { + *out = iface; + IMFPresentationDescriptor_AddRef(iface); + return S_OK; + } + + WARN("Unsupported %s.\n", debugstr_guid(riid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI presentation_descriptor_AddRef(IMFPresentationDescriptor *iface) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + ULONG refcount = InterlockedIncrement(&presentation_desc->attributes.ref); + + TRACE("%p, refcount %u.\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI presentation_descriptor_Release(IMFPresentationDescriptor *iface) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + ULONG refcount = InterlockedDecrement(&presentation_desc->attributes.ref); + unsigned int i; + + TRACE("%p, refcount %u.\n", iface, refcount); + + if (!refcount) + { + for (i = 0; i < presentation_desc->count; ++i) + { + if (presentation_desc->descriptors[i].descriptor) + IMFStreamDescriptor_Release(presentation_desc->descriptors[i].descriptor); + } + DeleteCriticalSection(&presentation_desc->cs); + heap_free(presentation_desc->descriptors); + heap_free(presentation_desc); + } + + return refcount; +} + +static HRESULT WINAPI presentation_descriptor_GetItem(IMFPresentationDescriptor *iface, REFGUID key, + PROPVARIANT *value) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_GetItem(&presentation_desc->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI presentation_descriptor_GetItemType(IMFPresentationDescriptor *iface, REFGUID key, + MF_ATTRIBUTE_TYPE *type) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_GetItemType(&presentation_desc->attributes.IMFAttributes_iface, key, type); +} + +static HRESULT WINAPI presentation_descriptor_CompareItem(IMFPresentationDescriptor *iface, REFGUID key, + REFPROPVARIANT value, BOOL *result) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_CompareItem(&presentation_desc->attributes.IMFAttributes_iface, key, value, result); +} + +static HRESULT WINAPI presentation_descriptor_Compare(IMFPresentationDescriptor *iface, IMFAttributes *attrs, + MF_ATTRIBUTES_MATCH_TYPE type, BOOL *result) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_Compare(&presentation_desc->attributes.IMFAttributes_iface, attrs, type, result); +} + +static HRESULT WINAPI presentation_descriptor_GetUINT32(IMFPresentationDescriptor *iface, REFGUID key, UINT32 *value) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_GetUINT32(&presentation_desc->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI presentation_descriptor_GetUINT64(IMFPresentationDescriptor *iface, REFGUID key, UINT64 *value) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_GetUINT64(&presentation_desc->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI presentation_descriptor_GetDouble(IMFPresentationDescriptor *iface, REFGUID key, double *value) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_GetDouble(&presentation_desc->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI presentation_descriptor_GetGUID(IMFPresentationDescriptor *iface, REFGUID key, GUID *value) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_GetGUID(&presentation_desc->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI presentation_descriptor_GetStringLength(IMFPresentationDescriptor *iface, REFGUID key, + UINT32 *length) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_GetStringLength(&presentation_desc->attributes.IMFAttributes_iface, key, length); +} + +static HRESULT WINAPI presentation_descriptor_GetString(IMFPresentationDescriptor *iface, REFGUID key, WCHAR *value, + UINT32 size, UINT32 *length) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_GetString(&presentation_desc->attributes.IMFAttributes_iface, key, value, size, length); +} + +static HRESULT WINAPI presentation_descriptor_GetAllocatedString(IMFPresentationDescriptor *iface, REFGUID key, + WCHAR **value, UINT32 *length) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_GetAllocatedString(&presentation_desc->attributes.IMFAttributes_iface, key, value, length); +} + +static HRESULT WINAPI presentation_descriptor_GetBlobSize(IMFPresentationDescriptor *iface, REFGUID key, UINT32 *size) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_GetBlobSize(&presentation_desc->attributes.IMFAttributes_iface, key, size); +} + +static HRESULT WINAPI presentation_descriptor_GetBlob(IMFPresentationDescriptor *iface, REFGUID key, UINT8 *buf, + UINT32 bufsize, UINT32 *blobsize) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_GetBlob(&presentation_desc->attributes.IMFAttributes_iface, key, buf, bufsize, blobsize); +} + +static HRESULT WINAPI presentation_descriptor_GetAllocatedBlob(IMFPresentationDescriptor *iface, REFGUID key, + UINT8 **buf, UINT32 *size) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_GetAllocatedBlob(&presentation_desc->attributes.IMFAttributes_iface, key, buf, size); +} + +static HRESULT WINAPI presentation_descriptor_GetUnknown(IMFPresentationDescriptor *iface, REFGUID key, + REFIID riid, void **ppv) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_GetUnknown(&presentation_desc->attributes.IMFAttributes_iface, key, riid, ppv); +} + +static HRESULT WINAPI presentation_descriptor_SetItem(IMFPresentationDescriptor *iface, REFGUID key, + REFPROPVARIANT value) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_SetItem(&presentation_desc->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI presentation_descriptor_DeleteItem(IMFPresentationDescriptor *iface, REFGUID key) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_DeleteItem(&presentation_desc->attributes.IMFAttributes_iface, key); +} + +static HRESULT WINAPI presentation_descriptor_DeleteAllItems(IMFPresentationDescriptor *iface) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_DeleteAllItems(&presentation_desc->attributes.IMFAttributes_iface); +} + +static HRESULT WINAPI presentation_descriptor_SetUINT32(IMFPresentationDescriptor *iface, REFGUID key, UINT32 value) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_SetUINT32(&presentation_desc->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI presentation_descriptor_SetUINT64(IMFPresentationDescriptor *iface, REFGUID key, UINT64 value) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_SetUINT64(&presentation_desc->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI presentation_descriptor_SetDouble(IMFPresentationDescriptor *iface, REFGUID key, double value) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_SetDouble(&presentation_desc->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI presentation_descriptor_SetGUID(IMFPresentationDescriptor *iface, REFGUID key, REFGUID value) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_SetGUID(&presentation_desc->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI presentation_descriptor_SetString(IMFPresentationDescriptor *iface, REFGUID key, + const WCHAR *value) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_SetString(&presentation_desc->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI presentation_descriptor_SetBlob(IMFPresentationDescriptor *iface, REFGUID key, const UINT8 *buf, + UINT32 size) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_SetBlob(&presentation_desc->attributes.IMFAttributes_iface, key, buf, size); +} + +static HRESULT WINAPI presentation_descriptor_SetUnknown(IMFPresentationDescriptor *iface, REFGUID key, + IUnknown *unknown) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_SetUnknown(&presentation_desc->attributes.IMFAttributes_iface, key, unknown); +} + +static HRESULT WINAPI presentation_descriptor_LockStore(IMFPresentationDescriptor *iface) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_LockStore(&presentation_desc->attributes.IMFAttributes_iface); +} + +static HRESULT WINAPI presentation_descriptor_UnlockStore(IMFPresentationDescriptor *iface) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_UnlockStore(&presentation_desc->attributes.IMFAttributes_iface); +} + +static HRESULT WINAPI presentation_descriptor_GetCount(IMFPresentationDescriptor *iface, UINT32 *items) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_GetCount(&presentation_desc->attributes.IMFAttributes_iface, items); +} + +static HRESULT WINAPI presentation_descriptor_GetItemByIndex(IMFPresentationDescriptor *iface, UINT32 index, GUID *key, + PROPVARIANT *value) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + return IMFAttributes_GetItemByIndex(&presentation_desc->attributes.IMFAttributes_iface, index, key, value); +} + +static HRESULT WINAPI presentation_descriptor_CopyAllItems(IMFPresentationDescriptor *iface, IMFAttributes *dest) +{ + FIXME("%p, %p.\n", iface, dest); + + return E_NOTIMPL; +} + +static HRESULT WINAPI presentation_descriptor_GetStreamDescriptorCount(IMFPresentationDescriptor *iface, DWORD *count) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + + TRACE("%p, %p.\n", iface, count); + + *count = presentation_desc->count; + + return S_OK; +} + +static HRESULT WINAPI presentation_descriptor_GetStreamDescriptorByIndex(IMFPresentationDescriptor *iface, DWORD index, + BOOL *selected, IMFStreamDescriptor **descriptor) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + + TRACE("%p, %u, %p, %p.\n", iface, index, selected, descriptor); + + if (index >= presentation_desc->count) + return E_INVALIDARG; + + EnterCriticalSection(&presentation_desc->cs); + *selected = presentation_desc->descriptors[index].selected; + LeaveCriticalSection(&presentation_desc->cs); + + *descriptor = presentation_desc->descriptors[index].descriptor; + IMFStreamDescriptor_AddRef(*descriptor); + + return S_OK; +} + +static HRESULT WINAPI presentation_descriptor_SelectStream(IMFPresentationDescriptor *iface, DWORD index) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + + TRACE("%p, %u.\n", iface, index); + + if (index >= presentation_desc->count) + return E_INVALIDARG; + + EnterCriticalSection(&presentation_desc->cs); + presentation_desc->descriptors[index].selected = TRUE; + LeaveCriticalSection(&presentation_desc->cs); + + return S_OK; +} + +static HRESULT WINAPI presentation_descriptor_DeselectStream(IMFPresentationDescriptor *iface, DWORD index) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + + TRACE("%p, %u.\n", iface, index); + + if (index >= presentation_desc->count) + return E_INVALIDARG; + + EnterCriticalSection(&presentation_desc->cs); + presentation_desc->descriptors[index].selected = FALSE; + LeaveCriticalSection(&presentation_desc->cs); + + return S_OK; +} + +static HRESULT WINAPI presentation_descriptor_Clone(IMFPresentationDescriptor *iface, + IMFPresentationDescriptor **descriptor) +{ + struct presentation_desc *presentation_desc = impl_from_IMFPresentationDescriptor(iface); + struct presentation_desc *object; + unsigned int i; + + TRACE("%p, %p.\n", iface, descriptor); + + object = heap_alloc_zero(sizeof(*object)); + if (!object) + return E_OUTOFMEMORY; + + presentation_descriptor_init(object, presentation_desc->count); + + EnterCriticalSection(&presentation_desc->cs); + + for (i = 0; i < presentation_desc->count; ++i) + { + object->descriptors[i] = presentation_desc->descriptors[i]; + IMFStreamDescriptor_AddRef(object->descriptors[i].descriptor); + } + /* FIXME: copy attributes */ + + LeaveCriticalSection(&presentation_desc->cs); + + *descriptor = &object->IMFPresentationDescriptor_iface; + + return S_OK; +} + +static const IMFPresentationDescriptorVtbl presentationdescriptorvtbl = +{ + presentation_descriptor_QueryInterface, + presentation_descriptor_AddRef, + presentation_descriptor_Release, + presentation_descriptor_GetItem, + presentation_descriptor_GetItemType, + presentation_descriptor_CompareItem, + presentation_descriptor_Compare, + presentation_descriptor_GetUINT32, + presentation_descriptor_GetUINT64, + presentation_descriptor_GetDouble, + presentation_descriptor_GetGUID, + presentation_descriptor_GetStringLength, + presentation_descriptor_GetString, + presentation_descriptor_GetAllocatedString, + presentation_descriptor_GetBlobSize, + presentation_descriptor_GetBlob, + presentation_descriptor_GetAllocatedBlob, + presentation_descriptor_GetUnknown, + presentation_descriptor_SetItem, + presentation_descriptor_DeleteItem, + presentation_descriptor_DeleteAllItems, + presentation_descriptor_SetUINT32, + presentation_descriptor_SetUINT64, + presentation_descriptor_SetDouble, + presentation_descriptor_SetGUID, + presentation_descriptor_SetString, + presentation_descriptor_SetBlob, + presentation_descriptor_SetUnknown, + presentation_descriptor_LockStore, + presentation_descriptor_UnlockStore, + presentation_descriptor_GetCount, + presentation_descriptor_GetItemByIndex, + presentation_descriptor_CopyAllItems, + presentation_descriptor_GetStreamDescriptorCount, + presentation_descriptor_GetStreamDescriptorByIndex, + presentation_descriptor_SelectStream, + presentation_descriptor_DeselectStream, + presentation_descriptor_Clone, +}; + +static HRESULT presentation_descriptor_init(struct presentation_desc *object, DWORD count) +{ + init_attribute_object(&object->attributes, 0); + object->IMFPresentationDescriptor_iface.lpVtbl = &presentationdescriptorvtbl; + object->descriptors = heap_alloc_zero(count * sizeof(*object->descriptors)); + if (!object->descriptors) + { + heap_free(object); + return E_OUTOFMEMORY; + } + object->count = count; + InitializeCriticalSection(&object->cs); + + return S_OK; +} + +/*********************************************************************** + * MFCreatePresentationDescriptor (mfplat.@) + */ +HRESULT WINAPI MFCreatePresentationDescriptor(DWORD count, IMFStreamDescriptor **descriptors, + IMFPresentationDescriptor **out) +{ + struct presentation_desc *object; + unsigned int i; + HRESULT hr; + + TRACE("%u, %p, %p.\n", count, descriptors, out); + + if (!count) + return E_INVALIDARG; + + for (i = 0; i < count; ++i) + { + if (!descriptors[i]) + return E_INVALIDARG; + } + + object = heap_alloc_zero(sizeof(*object)); + if (!object) + return E_OUTOFMEMORY; + + if (FAILED(hr = presentation_descriptor_init(object, count))) + { + heap_free(object); + return hr; + } + + for (i = 0; i < count; ++i) + { + object->descriptors[i].descriptor = descriptors[i]; + IMFStreamDescriptor_AddRef(object->descriptors[i].descriptor); + } + + *out = &object->IMFPresentationDescriptor_iface; + + return S_OK; +} diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec index 116ec61289..741dfafad3 100644 --- a/dlls/mfplat/mfplat.spec +++ b/dlls/mfplat/mfplat.spec @@ -55,7 +55,7 @@ @ stdcall MFCreateMemoryBuffer(long ptr) @ stub MFCreateMemoryStream @ stub MFCreatePathFromURL -@ stub MFCreatePresentationDescriptor +@ stdcall MFCreatePresentationDescriptor(long ptr ptr) @ stdcall MFCreateSample(ptr) @ stub MFCreateSocket @ stub MFCreateSocketListener diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 4405bd9282..aa4104d9ed 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -1429,6 +1429,81 @@ static void test_event_queue(void) ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr); }
+static void test_presentation_descriptor(void) +{ + IMFStreamDescriptor *stream_desc[2], *stream_desc2; + IMFPresentationDescriptor *pd, *pd2; + IMFMediaType *media_type; + unsigned int i; + BOOL selected; + DWORD count; + HRESULT hr; + + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr); + + for (i = 0; i < ARRAY_SIZE(stream_desc); ++i) + { + hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[i]); + ok(hr == S_OK, "Failed to create descriptor, hr %#x.\n", hr); + } + + hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd); + ok(hr == S_OK, "Failed to create presentation descriptor, hr %#x.\n", hr); + + hr = IMFPresentationDescriptor_GetStreamDescriptorCount(pd, &count); + ok(count == ARRAY_SIZE(stream_desc), "Unexpected count %u.\n", count); + + for (i = 0; i < count; ++i) + { + hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, i, &selected, &stream_desc2); + ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr); + ok(!selected, "Unexpected selected state.\n"); + ok(stream_desc[i] == stream_desc2, "Unexpected object.\n"); + IMFStreamDescriptor_Release(stream_desc2); + } + + hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 10, &selected, &stream_desc2); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + hr = IMFPresentationDescriptor_SelectStream(pd, 10); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + hr = IMFPresentationDescriptor_SelectStream(pd, 0); + ok(hr == S_OK, "Failed to select a stream, hr %#x.\n", hr); + + hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &stream_desc2); + ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr); + ok(!!selected, "Unexpected selected state.\n"); + IMFStreamDescriptor_Release(stream_desc2); + + hr = IMFPresentationDescriptor_Clone(pd, &pd2); + ok(hr == S_OK, "Failed to clone, hr %#x.\n", hr); + + hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd2, 0, &selected, &stream_desc2); + ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr); + ok(!!selected, "Unexpected selected state.\n"); + IMFStreamDescriptor_Release(stream_desc2); + + IMFPresentationDescriptor_Release(pd); + + for (i = 0; i < ARRAY_SIZE(stream_desc); ++i) + { + IMFStreamDescriptor_Release(stream_desc[i]); + } + + /* Partially initialized array. */ + hr = MFCreateStreamDescriptor(0, 1, &media_type, &stream_desc[1]); + ok(hr == S_OK, "Failed to create descriptor, hr %#x.\n", hr); + stream_desc[0] = NULL; + + hr = MFCreatePresentationDescriptor(ARRAY_SIZE(stream_desc), stream_desc, &pd); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + IMFStreamDescriptor_Release(stream_desc[1]); + IMFMediaType_Release(media_type); +} + START_TEST(mfplat) { CoInitialize(NULL); @@ -1454,6 +1529,7 @@ START_TEST(mfplat) test_serial_queue(); test_periodic_callback(); test_event_queue(); + test_presentation_descriptor();
CoUninitialize(); } diff --git a/include/mfidl.idl b/include/mfidl.idl index 48d7c8e501..21157ee95d 100644 --- a/include/mfidl.idl +++ b/include/mfidl.idl @@ -351,6 +351,8 @@ cpp_quote("HRESULT WINAPI MFCreateMediaSession(IMFAttributes *config, IMFMediaSe cpp_quote("HRESULT WINAPI MFCreateMFByteStreamOnStream(IStream *stream, IMFByteStream **bytestream);" ) cpp_quote("HRESULT WINAPI MFCreateMFByteStreamOnStreamEx(IUnknown *stream, IMFByteStream **bytestream);") cpp_quote("HRESULT WINAPI MFCreatePresentationClock(IMFPresentationClock **clock);") +cpp_quote("HRESULT WINAPI MFCreatePresentationDescriptor(DWORD count, IMFStreamDescriptor **descriptors,") +cpp_quote(" IMFPresentationDescriptor **presentation_desc);") cpp_quote("HRESULT WINAPI MFCreateSequencerSource(IUnknown *reserved, IMFSequencerSource **seq_source);" ) cpp_quote("HRESULT WINAPI MFCreateSourceResolver(IMFSourceResolver **resolver);") cpp_quote("HRESULT WINAPI MFCreateStreamDescriptor(DWORD identifier, DWORD cMediaTypes,")
On Tue, Mar 5, 2019 at 8:50 AM Nikolay Sivov nsivov@codeweavers.com wrote:
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
dlls/mfplat/mediatype.c | 463 +++++++++++++++++++++++++++++++++++++ dlls/mfplat/mfplat.spec | 2 +- dlls/mfplat/tests/mfplat.c | 76 ++++++ include/mfidl.idl | 2 + 4 files changed, 542 insertions(+), 1 deletion(-)
Hi Nikolay,
A stub implementation of the presentation descriptor is already present in main.c. Can't you use/move that one?
Sven
On 3/5/19 4:35 PM, Sven Baars wrote:
On Tue, Mar 5, 2019 at 8:50 AM Nikolay Sivov nsivov@codeweavers.com wrote:
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com
dlls/mfplat/mediatype.c | 463 +++++++++++++++++++++++++++++++++++++ dlls/mfplat/mfplat.spec | 2 +- dlls/mfplat/tests/mfplat.c | 76 ++++++ include/mfidl.idl | 2 + 4 files changed, 542 insertions(+), 1 deletion(-)
Hi Nikolay,
A stub implementation of the presentation descriptor is already present in main.c. Can't you use/move that one?
Hi.
The issue is that mfplat should not have its own media source implementation, that should be handled by plugin modules.
Those external media sources then can use stock implementation of presentation descriptor or implement something else. Now, to create this stock implementation instance you'll need stream descriptor, for which you'll need media types.
That's why I left existing stubs for now, assuming they were added to fix some crashes. Eventually media source one will have to be removed.
Sven
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/Makefile.in | 1 + dlls/mfplat/buffer.c | 216 +++++++++++++++++++++++++++++++++++++ dlls/mfplat/main.c | 174 ------------------------------ dlls/mfplat/mfplat.spec | 2 +- dlls/mfplat/tests/mfplat.c | 52 ++++++--- include/mfapi.h | 16 +++ 6 files changed, 273 insertions(+), 188 deletions(-) create mode 100644 dlls/mfplat/buffer.c
diff --git a/dlls/mfplat/Makefile.in b/dlls/mfplat/Makefile.in index 261c121cab..a117ede271 100644 --- a/dlls/mfplat/Makefile.in +++ b/dlls/mfplat/Makefile.in @@ -3,6 +3,7 @@ IMPORTLIB = mfplat IMPORTS = advapi32 ole32
C_SRCS = \ + buffer.c \ main.c \ mediatype.c \ queue.c diff --git a/dlls/mfplat/buffer.c b/dlls/mfplat/buffer.c new file mode 100644 index 0000000000..e206b356dc --- /dev/null +++ b/dlls/mfplat/buffer.c @@ -0,0 +1,216 @@ +/* + * Copyright 2018 Alistair Leslie-Hughes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include "mfplat_private.h" + +#include "wine/debug.h" +#include "wine/heap.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mfplat); + +struct memory_buffer +{ + IMFMediaBuffer IMFMediaBuffer_iface; + LONG refcount; + + BYTE *data; + DWORD max_length; + DWORD current_length; +}; + +static inline struct memory_buffer *impl_from_IMFMediaBuffer(IMFMediaBuffer *iface) +{ + return CONTAINING_RECORD(iface, struct memory_buffer, IMFMediaBuffer_iface); +} + +static HRESULT WINAPI memory_buffer_QueryInterface(IMFMediaBuffer *iface, REFIID riid, void **out) +{ + struct memory_buffer *buffer = impl_from_IMFMediaBuffer(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out); + + if (IsEqualIID(riid, &IID_IMFMediaBuffer) || + IsEqualIID(riid, &IID_IUnknown)) + { + *out = &buffer->IMFMediaBuffer_iface; + } + else + { + FIXME("(%s, %p)\n", debugstr_guid(riid), out); + *out = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*out); + return S_OK; +} + +static ULONG WINAPI memory_buffer_AddRef(IMFMediaBuffer *iface) +{ + struct memory_buffer *buffer = impl_from_IMFMediaBuffer(iface); + ULONG refcount = InterlockedIncrement(&buffer->refcount); + + TRACE("%p, refcount %u.\n", buffer, refcount); + + return refcount; +} + +static ULONG WINAPI memory_buffer_Release(IMFMediaBuffer *iface) +{ + struct memory_buffer *buffer = impl_from_IMFMediaBuffer(iface); + ULONG refcount = InterlockedDecrement(&buffer->refcount); + + TRACE("%p, refcount %u.\n", iface, refcount); + + if (!refcount) + { + heap_free(buffer->data); + heap_free(buffer); + } + + return refcount; +} + +static HRESULT WINAPI memory_buffer_Lock(IMFMediaBuffer *iface, BYTE **data, DWORD *max_length, DWORD *current_length) +{ + struct memory_buffer *buffer = impl_from_IMFMediaBuffer(iface); + + TRACE("%p, %p %p, %p.\n", iface, data, max_length, current_length); + + if (!data) + return E_INVALIDARG; + + *data = buffer->data; + if (max_length) + *max_length = buffer->max_length; + if (current_length) + *current_length = buffer->current_length; + + return S_OK; +} + +static HRESULT WINAPI memory_buffer_Unlock(IMFMediaBuffer *iface) +{ + TRACE("%p.\n", iface); + + return S_OK; +} + +static HRESULT WINAPI memory_buffer_GetCurrentLength(IMFMediaBuffer *iface, DWORD *current_length) +{ + struct memory_buffer *buffer = impl_from_IMFMediaBuffer(iface); + + TRACE("%p.\n", iface); + + if (!current_length) + return E_INVALIDARG; + + *current_length = buffer->current_length; + + return S_OK; +} + +static HRESULT WINAPI memory_buffer_SetCurrentLength(IMFMediaBuffer *iface, DWORD current_length) +{ + struct memory_buffer *buffer = impl_from_IMFMediaBuffer(iface); + + TRACE("%p, %u.\n", iface, current_length); + + if (current_length > buffer->max_length) + return E_INVALIDARG; + + buffer->current_length = current_length; + + return S_OK; +} + +static HRESULT WINAPI memory_buffer_GetMaxLength(IMFMediaBuffer *iface, DWORD *max_length) +{ + struct memory_buffer *buffer = impl_from_IMFMediaBuffer(iface); + + TRACE("%p, %p.\n", iface, max_length); + + if (!max_length) + return E_INVALIDARG; + + *max_length = buffer->max_length; + + return S_OK; +} + +static const IMFMediaBufferVtbl memorybuffervtbl = +{ + memory_buffer_QueryInterface, + memory_buffer_AddRef, + memory_buffer_Release, + memory_buffer_Lock, + memory_buffer_Unlock, + memory_buffer_GetCurrentLength, + memory_buffer_SetCurrentLength, + memory_buffer_GetMaxLength, +}; + +static HRESULT create_memory_buffer(DWORD max_length, DWORD alignment, IMFMediaBuffer **buffer) +{ + struct memory_buffer *object; + + if (!buffer) + return E_INVALIDARG; + + object = heap_alloc(sizeof(*object)); + if (!object) + return E_OUTOFMEMORY; + + object->data = heap_alloc((max_length + alignment) & ~alignment); + if (!object->data) + { + heap_free(object); + return E_OUTOFMEMORY; + } + + object->IMFMediaBuffer_iface.lpVtbl = &memorybuffervtbl; + object->refcount = 1; + object->max_length = max_length; + object->current_length = 0; + + *buffer = &object->IMFMediaBuffer_iface; + + return S_OK; +} + +/*********************************************************************** + * MFCreateMemoryBuffer (mfplat.@) + */ +HRESULT WINAPI MFCreateMemoryBuffer(DWORD max_length, IMFMediaBuffer **buffer) +{ + TRACE("%u, %p.\n", max_length, buffer); + + return create_memory_buffer(max_length, MF_1_BYTE_ALIGNMENT, buffer); +} + +/*********************************************************************** + * MFCreateAlignedMemoryBuffer (mfplat.@) + */ +HRESULT WINAPI MFCreateAlignedMemoryBuffer(DWORD max_length, DWORD alignment, IMFMediaBuffer **buffer) +{ + TRACE("%u, %u, %p.\n", max_length, alignment, buffer); + + return create_memory_buffer(max_length, alignment, buffer); +} diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index 2217f3fb94..57943cf115 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -2798,180 +2798,6 @@ HRESULT WINAPI MFCreateEventQueue(IMFMediaEventQueue **queue) return S_OK; }
-typedef struct _mfbuffer -{ - IMFMediaBuffer IMFMediaBuffer_iface; - LONG ref; - - BYTE *buffer; - DWORD max_length; - DWORD current; -} mfbuffer; - -static inline mfbuffer *impl_from_IMFMediaBuffer(IMFMediaBuffer *iface) -{ - return CONTAINING_RECORD(iface, mfbuffer, IMFMediaBuffer_iface); -} - -static HRESULT WINAPI mfbuffer_QueryInterface(IMFMediaBuffer *iface, REFIID riid, void **out) -{ - mfbuffer *This = impl_from_IMFMediaBuffer(iface); - - TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), out); - - if(IsEqualGUID(riid, &IID_IUnknown) || - IsEqualGUID(riid, &IID_IMFMediaBuffer)) - { - *out = &This->IMFMediaBuffer_iface; - } - else - { - FIXME("(%s, %p)\n", debugstr_guid(riid), out); - *out = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*out); - return S_OK; -} - -static ULONG WINAPI mfbuffer_AddRef(IMFMediaBuffer *iface) -{ - mfbuffer *This = impl_from_IMFMediaBuffer(iface); - ULONG ref = InterlockedIncrement(&This->ref); - - TRACE("(%p) ref=%u\n", This, ref); - - return ref; -} - -static ULONG WINAPI mfbuffer_Release(IMFMediaBuffer *iface) -{ - mfbuffer *This = impl_from_IMFMediaBuffer(iface); - ULONG ref = InterlockedDecrement(&This->ref); - - TRACE("(%p) ref=%u\n", This, ref); - - if (!ref) - { - heap_free(This->buffer); - heap_free(This); - } - - return ref; -} - -static HRESULT WINAPI mfbuffer_Lock(IMFMediaBuffer *iface, BYTE **buffer, DWORD *max, DWORD *current) -{ - mfbuffer *This = impl_from_IMFMediaBuffer(iface); - - TRACE("%p, %p %p, %p\n", This, buffer, max, current); - - if(!buffer) - return E_INVALIDARG; - - *buffer = This->buffer; - if(max) - *max = This->max_length; - if(current) - *current = This->current; - - return S_OK; -} - -static HRESULT WINAPI mfbuffer_Unlock(IMFMediaBuffer *iface) -{ - mfbuffer *This = impl_from_IMFMediaBuffer(iface); - - TRACE("%p\n", This); - - return S_OK; -} - -static HRESULT WINAPI mfbuffer_GetCurrentLength(IMFMediaBuffer *iface, DWORD *current) -{ - mfbuffer *This = impl_from_IMFMediaBuffer(iface); - - TRACE("%p\n", This); - - if(!current) - return E_INVALIDARG; - - *current = This->current; - - return S_OK; -} - -static HRESULT WINAPI mfbuffer_SetCurrentLength(IMFMediaBuffer *iface, DWORD current) -{ - mfbuffer *This = impl_from_IMFMediaBuffer(iface); - - TRACE("%p, %u\n", This, current); - - if(current > This->max_length) - return E_INVALIDARG; - - This->current = current; - - return S_OK; -} - -static HRESULT WINAPI mfbuffer_GetMaxLength(IMFMediaBuffer *iface, DWORD *max) -{ - mfbuffer *This = impl_from_IMFMediaBuffer(iface); - - TRACE("%p, %p\n", This, max); - - if(!max) - return E_INVALIDARG; - - *max = This->max_length; - - return S_OK; -} - -static const IMFMediaBufferVtbl mfbuffer_vtbl = -{ - mfbuffer_QueryInterface, - mfbuffer_AddRef, - mfbuffer_Release, - mfbuffer_Lock, - mfbuffer_Unlock, - mfbuffer_GetCurrentLength, - mfbuffer_SetCurrentLength, - mfbuffer_GetMaxLength -}; - -HRESULT WINAPI MFCreateMemoryBuffer(DWORD max_length, IMFMediaBuffer **buffer) -{ - mfbuffer *object; - BYTE *bytes; - - TRACE("%u, %p\n", max_length, buffer); - - if(!buffer) - return E_INVALIDARG; - - object = heap_alloc( sizeof(*object) ); - if(!object) - return E_OUTOFMEMORY; - - bytes = heap_alloc( max_length ); - if(!bytes) - { - heap_free(object); - return E_OUTOFMEMORY; - } - - object->ref = 1; - object->max_length = max_length; - object->current = 0; - object->buffer = bytes; - object->IMFMediaBuffer_iface.lpVtbl = &mfbuffer_vtbl; - *buffer = &object->IMFMediaBuffer_iface; - - return S_OK; -}
typedef struct _mfsample { diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec index 741dfafad3..900efc3780 100644 --- a/dlls/mfplat/mfplat.spec +++ b/dlls/mfplat/mfplat.spec @@ -37,7 +37,7 @@ @ stub MFConvertToFP16Array @ stdcall MFCopyImage(ptr long ptr long long long) @ stub MFCreateAMMediaTypeFromMFMediaType -@ stub MFCreateAlignedMemoryBuffer +@ stdcall MFCreateAlignedMemoryBuffer(long long ptr) @ stdcall MFCreateAsyncResult(ptr ptr ptr ptr) @ stdcall MFCreateAttributes(ptr long) @ stub MFCreateAudioMediaType diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index aa4104d9ed..674bcf418e 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -42,7 +42,6 @@ static HRESULT (WINAPI *pMFCopyImage)(BYTE *dest, LONG deststride, const BYTE *s DWORD width, DWORD lines); static HRESULT (WINAPI *pMFCreateSourceResolver)(IMFSourceResolver **resolver); static HRESULT (WINAPI *pMFCreateMFByteStreamOnStream)(IStream *stream, IMFByteStream **bytestream); -static HRESULT (WINAPI *pMFCreateMemoryBuffer)(DWORD max_length, IMFMediaBuffer **buffer); static void* (WINAPI *pMFHeapAlloc)(SIZE_T size, ULONG flags, char *file, int line, EAllocationType type); static void (WINAPI *pMFHeapFree)(void *p); static HRESULT (WINAPI *pMFPutWaitingWorkItem)(HANDLE event, LONG priority, IMFAsyncResult *result, MFWORKITEM_KEY *key); @@ -323,7 +322,6 @@ static void init_functions(void) X(MFCopyImage); X(MFCreateSourceResolver); X(MFCreateMFByteStreamOnStream); - X(MFCreateMemoryBuffer); X(MFHeapAlloc); X(MFHeapFree); X(MFPutWaitingWorkItem); @@ -602,23 +600,17 @@ static void test_MFCreateFile(void) DeleteFileW(newfilename); }
-static void test_MFCreateMemoryBuffer(void) +static void test_system_memory_buffer(void) { IMFMediaBuffer *buffer; HRESULT hr; DWORD length, max; BYTE *data, *data2;
- if(!pMFCreateMemoryBuffer) - { - win_skip("MFCreateMemoryBuffer() not found\n"); - return; - } - - hr = pMFCreateMemoryBuffer(1024, NULL); + hr = MFCreateMemoryBuffer(1024, NULL); ok(hr == E_INVALIDARG || hr == E_POINTER, "got 0x%08x\n", hr);
- hr = pMFCreateMemoryBuffer(0, &buffer); + hr = MFCreateMemoryBuffer(0, &buffer); ok(hr == S_OK, "got 0x%08x\n", hr); if(buffer) { @@ -629,7 +621,7 @@ static void test_MFCreateMemoryBuffer(void) IMFMediaBuffer_Release(buffer); }
- hr = pMFCreateMemoryBuffer(1024, &buffer); + hr = MFCreateMemoryBuffer(1024, &buffer); ok(hr == S_OK, "got 0x%08x\n", hr);
hr = IMFMediaBuffer_GetMaxLength(buffer, NULL); @@ -686,6 +678,40 @@ static void test_MFCreateMemoryBuffer(void) ok(hr == S_OK, "got 0x%08x\n", hr);
IMFMediaBuffer_Release(buffer); + + /* Aligned buffer. */ + hr = MFCreateAlignedMemoryBuffer(201, MF_8_BYTE_ALIGNMENT, &buffer); + ok(hr == S_OK, "Failed to create memory buffer, hr %#x.\n", hr); + + hr = IMFMediaBuffer_GetCurrentLength(buffer, &length); + ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr); + ok(length == 0, "Unexpected current length %u.\n", length); + + hr = IMFMediaBuffer_SetCurrentLength(buffer, 1); + ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr); + hr = IMFMediaBuffer_GetCurrentLength(buffer, &length); + ok(hr == S_OK, "Failed to get current length, hr %#x.\n", hr); + ok(length == 1, "Unexpected current length %u.\n", length); + + hr = IMFMediaBuffer_GetMaxLength(buffer, &length); + ok(hr == S_OK, "Failed to get max length, hr %#x.\n", hr); + ok(length == 201, "Unexpected max length %u.\n", length); + + hr = IMFMediaBuffer_SetCurrentLength(buffer, 202); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + hr = IMFMediaBuffer_GetMaxLength(buffer, &length); + ok(hr == S_OK, "Failed to get max length, hr %#x.\n", hr); + ok(length == 201, "Unexpected max length %u.\n", length); + hr = IMFMediaBuffer_SetCurrentLength(buffer, 10); + ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr); + + hr = IMFMediaBuffer_Lock(buffer, &data, &max, &length); + ok(hr == S_OK, "Failed to lock, hr %#x.\n", hr); + ok(max == 201 && length == 10, "Unexpected length.\n"); + hr = IMFMediaBuffer_Unlock(buffer); + ok(hr == S_OK, "Failed to unlock, hr %#x.\n", hr); + + IMFMediaBuffer_Release(buffer); }
static void test_MFSample(void) @@ -1518,7 +1544,7 @@ START_TEST(mfplat) test_MFSample(); test_MFCreateFile(); test_MFCreateMFByteStreamOnStream(); - test_MFCreateMemoryBuffer(); + test_system_memory_buffer(); test_source_resolver(); test_MFCreateAsyncResult(); test_allocate_queue(); diff --git a/include/mfapi.h b/include/mfapi.h index 4560d5dee7..4062e2fd13 100644 --- a/include/mfapi.h +++ b/include/mfapi.h @@ -97,11 +97,27 @@ typedef enum
typedef void (CALLBACK *MFPERIODICCALLBACK)(IUnknown *context);
+#define MF_1_BYTE_ALIGNMENT 0x00000000 +#define MF_2_BYTE_ALIGNMENT 0x00000001 +#define MF_4_BYTE_ALIGNMENT 0x00000003 +#define MF_8_BYTE_ALIGNMENT 0x00000007 +#define MF_16_BYTE_ALIGNMENT 0x0000000f +#define MF_32_BYTE_ALIGNMENT 0x0000001f +#define MF_64_BYTE_ALIGNMENT 0x0000003f +#define MF_128_BYTE_ALIGNMENT 0x0000007f +#define MF_256_BYTE_ALIGNMENT 0x000000ff +#define MF_512_BYTE_ALIGNMENT 0x000001ff +#define MF_1024_BYTE_ALIGNMENT 0x000003ff +#define MF_2048_BYTE_ALIGNMENT 0x000007ff +#define MF_4096_BYTE_ALIGNMENT 0x00000fff +#define MF_8192_BYTE_ALIGNMENT 0x00001fff + HRESULT WINAPI MFAddPeriodicCallback(MFPERIODICCALLBACK callback, IUnknown *context, DWORD *key); HRESULT WINAPI MFAllocateWorkQueue(DWORD *queue); HRESULT WINAPI MFAllocateWorkQueueEx(MFASYNC_WORKQUEUE_TYPE queue_type, DWORD *queue); HRESULT WINAPI MFCancelWorkItem(MFWORKITEM_KEY key); HRESULT WINAPI MFCopyImage(BYTE *dest, LONG deststride, const BYTE *src, LONG srcstride, DWORD width, DWORD lines); +HRESULT WINAPI MFCreateAlignedMemoryBuffer(DWORD max_length, DWORD alignment, IMFMediaBuffer **buffer); HRESULT WINAPI MFCreateAttributes(IMFAttributes **attributes, UINT32 size); HRESULT WINAPI MFCreateAsyncResult(IUnknown *object, IMFAsyncCallback *callback, IUnknown *state, IMFAsyncResult **result); HRESULT WINAPI MFCreateCollection(IMFCollection **collection);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/buffer.c | 409 +++++++++++++++++++++++++++++++++++++++ dlls/mfplat/main.c | 444 ------------------------------------------- 2 files changed, 409 insertions(+), 444 deletions(-)
diff --git a/dlls/mfplat/buffer.c b/dlls/mfplat/buffer.c index e206b356dc..f60c015c6c 100644 --- a/dlls/mfplat/buffer.c +++ b/dlls/mfplat/buffer.c @@ -35,11 +35,22 @@ struct memory_buffer DWORD current_length; };
+struct sample +{ + struct attributes attributes; + IMFSample IMFSample_iface; +}; + static inline struct memory_buffer *impl_from_IMFMediaBuffer(IMFMediaBuffer *iface) { return CONTAINING_RECORD(iface, struct memory_buffer, IMFMediaBuffer_iface); }
+static inline struct sample *impl_from_IMFSample(IMFSample *iface) +{ + return CONTAINING_RECORD(iface, struct sample, IMFSample_iface); +} + static HRESULT WINAPI memory_buffer_QueryInterface(IMFMediaBuffer *iface, REFIID riid, void **out) { struct memory_buffer *buffer = impl_from_IMFMediaBuffer(iface); @@ -214,3 +225,401 @@ HRESULT WINAPI MFCreateAlignedMemoryBuffer(DWORD max_length, DWORD alignment, IM
return create_memory_buffer(max_length, alignment, buffer); } + +static HRESULT WINAPI sample_QueryInterface(IMFSample *iface, REFIID riid, void **out) +{ + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out); + + if (IsEqualIID(riid, &IID_IMFSample) || + IsEqualIID(riid, &IID_IMFAttributes) || + IsEqualIID(riid, &IID_IUnknown)) + { + *out = iface; + IMFSample_AddRef(iface); + return S_OK; + } + + WARN("Unsupported %s.\n", debugstr_guid(riid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI sample_AddRef(IMFSample *iface) +{ + struct sample *sample = impl_from_IMFSample(iface); + ULONG refcount = InterlockedIncrement(&sample->attributes.ref); + + TRACE("%p, refcount %u.\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI sample_Release(IMFSample *iface) +{ + struct sample *sample = impl_from_IMFSample(iface); + ULONG refcount = InterlockedDecrement(&sample->attributes.ref); + + TRACE("%p, refcount %u.\n", iface, refcount); + + if (!refcount) + { + heap_free(sample); + } + + return refcount; +} + +static HRESULT WINAPI sample_GetItem(IMFSample *iface, REFGUID key, PROPVARIANT *value) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_GetItem(&sample->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI sample_GetItemType(IMFSample *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_GetItemType(&sample->attributes.IMFAttributes_iface, key, type); +} + +static HRESULT WINAPI sample_CompareItem(IMFSample *iface, REFGUID key, REFPROPVARIANT value, BOOL *result) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_CompareItem(&sample->attributes.IMFAttributes_iface, key, value, result); +} + +static HRESULT WINAPI sample_Compare(IMFSample *iface, IMFAttributes *theirs, MF_ATTRIBUTES_MATCH_TYPE type, + BOOL *result) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_Compare(&sample->attributes.IMFAttributes_iface, theirs, type, result); +} + +static HRESULT WINAPI sample_GetUINT32(IMFSample *iface, REFGUID key, UINT32 *value) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_GetUINT32(&sample->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI sample_GetUINT64(IMFSample *iface, REFGUID key, UINT64 *value) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_GetUINT64(&sample->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI sample_GetDouble(IMFSample *iface, REFGUID key, double *value) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_GetDouble(&sample->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI sample_GetGUID(IMFSample *iface, REFGUID key, GUID *value) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_GetGUID(&sample->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI sample_GetStringLength(IMFSample *iface, REFGUID key, UINT32 *length) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_GetStringLength(&sample->attributes.IMFAttributes_iface, key, length); +} + +static HRESULT WINAPI sample_GetString(IMFSample *iface, REFGUID key, WCHAR *value, UINT32 size, UINT32 *length) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_GetString(&sample->attributes.IMFAttributes_iface, key, value, size, length); +} + +static HRESULT WINAPI sample_GetAllocatedString(IMFSample *iface, REFGUID key, WCHAR **value, UINT32 *length) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_GetAllocatedString(&sample->attributes.IMFAttributes_iface, key, value, length); +} + +static HRESULT WINAPI sample_GetBlobSize(IMFSample *iface, REFGUID key, UINT32 *size) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_GetBlobSize(&sample->attributes.IMFAttributes_iface, key, size); +} + +static HRESULT WINAPI sample_GetBlob(IMFSample *iface, REFGUID key, UINT8 *buf, UINT32 bufsize, UINT32 *blobsize) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_GetBlob(&sample->attributes.IMFAttributes_iface, key, buf, bufsize, blobsize); +} + +static HRESULT WINAPI sample_GetAllocatedBlob(IMFSample *iface, REFGUID key, UINT8 **buf, UINT32 *size) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_GetAllocatedBlob(&sample->attributes.IMFAttributes_iface, key, buf, size); +} + +static HRESULT WINAPI sample_GetUnknown(IMFSample *iface, REFGUID key, REFIID riid, void **ppv) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_GetUnknown(&sample->attributes.IMFAttributes_iface, key, riid, ppv); +} + +static HRESULT WINAPI sample_SetItem(IMFSample *iface, REFGUID key, REFPROPVARIANT value) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_SetItem(&sample->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI sample_DeleteItem(IMFSample *iface, REFGUID key) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_DeleteItem(&sample->attributes.IMFAttributes_iface, key); +} + +static HRESULT WINAPI sample_DeleteAllItems(IMFSample *iface) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_DeleteAllItems(&sample->attributes.IMFAttributes_iface); +} + +static HRESULT WINAPI sample_SetUINT32(IMFSample *iface, REFGUID key, UINT32 value) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_SetUINT32(&sample->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI sample_SetUINT64(IMFSample *iface, REFGUID key, UINT64 value) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_SetUINT64(&sample->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI sample_SetDouble(IMFSample *iface, REFGUID key, double value) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_SetDouble(&sample->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI sample_SetGUID(IMFSample *iface, REFGUID key, REFGUID value) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_SetGUID(&sample->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI sample_SetString(IMFSample *iface, REFGUID key, const WCHAR *value) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_SetString(&sample->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI sample_SetBlob(IMFSample *iface, REFGUID key, const UINT8 *buf, UINT32 size) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_SetBlob(&sample->attributes.IMFAttributes_iface, key, buf, size); +} + +static HRESULT WINAPI sample_SetUnknown(IMFSample *iface, REFGUID key, IUnknown *unknown) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_SetUnknown(&sample->attributes.IMFAttributes_iface, key, unknown); +} + +static HRESULT WINAPI sample_LockStore(IMFSample *iface) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_LockStore(&sample->attributes.IMFAttributes_iface); +} + +static HRESULT WINAPI sample_UnlockStore(IMFSample *iface) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_UnlockStore(&sample->attributes.IMFAttributes_iface); +} + +static HRESULT WINAPI sample_GetCount(IMFSample *iface, UINT32 *items) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_GetCount(&sample->attributes.IMFAttributes_iface, items); +} + +static HRESULT WINAPI sample_GetItemByIndex(IMFSample *iface, UINT32 index, GUID *key, PROPVARIANT *value) +{ + struct sample *sample = impl_from_IMFSample(iface); + return IMFAttributes_GetItemByIndex(&sample->attributes.IMFAttributes_iface, index, key, value); +} + +static HRESULT WINAPI sample_CopyAllItems(IMFSample *iface, IMFAttributes *dest) +{ + FIXME("%p, %p.\n", iface, dest); + + return E_NOTIMPL; +} + +static HRESULT WINAPI sample_GetSampleFlags(IMFSample *iface, DWORD *flags) +{ + FIXME("%p, %p.\n", iface, flags); + + return E_NOTIMPL; +} + +static HRESULT WINAPI sample_SetSampleFlags(IMFSample *iface, DWORD flags) +{ + FIXME("%p, %#x.\n", iface, flags); + + return E_NOTIMPL; +} + +static HRESULT WINAPI sample_GetSampleTime(IMFSample *iface, LONGLONG *sampletime) +{ + FIXME("%p, %p.\n", iface, sampletime); + + return E_NOTIMPL; +} + +static HRESULT WINAPI sample_SetSampleTime(IMFSample *iface, LONGLONG sampletime) +{ + FIXME("%p, %s.\n", iface, wine_dbgstr_longlong(sampletime)); + + return E_NOTIMPL; +} + +static HRESULT WINAPI sample_GetSampleDuration(IMFSample *iface, LONGLONG *duration) +{ + FIXME("%p, %p.\n", iface, duration); + + return E_NOTIMPL; +} + +static HRESULT WINAPI sample_SetSampleDuration(IMFSample *iface, LONGLONG duration) +{ + FIXME("%p, %s.\n", iface, wine_dbgstr_longlong(duration)); + + return E_NOTIMPL; +} + +static HRESULT WINAPI sample_GetBufferCount(IMFSample *iface, DWORD *count) +{ + FIXME("%p, %p.\n", iface, count); + + if (*count) + *count = 0; + + return S_OK; +} + +static HRESULT WINAPI sample_GetBufferByIndex(IMFSample *iface, DWORD index, IMFMediaBuffer **buffer) +{ + FIXME("%p, %u, %p.\n", iface, index, buffer); + + return E_NOTIMPL; +} + +static HRESULT WINAPI sample_ConvertToContiguousBuffer(IMFSample *iface, IMFMediaBuffer **buffer) +{ + FIXME("%p, %p.\n", iface, buffer); + + return E_NOTIMPL; +} + +static HRESULT WINAPI sample_AddBuffer(IMFSample *iface, IMFMediaBuffer *buffer) +{ + FIXME("%p, %p.\n", iface, buffer); + + return E_NOTIMPL; +} + +static HRESULT WINAPI sample_RemoveBufferByIndex(IMFSample *iface, DWORD index) +{ + FIXME("%p, %u.\n", iface, index); + + return E_NOTIMPL; +} + +static HRESULT WINAPI sample_RemoveAllBuffers(IMFSample *iface) +{ + FIXME("%p.\n", iface); + + return E_NOTIMPL; +} + +static HRESULT WINAPI sample_GetTotalLength(IMFSample *iface, DWORD *length) +{ + FIXME("%p, %p.\n", iface, length); + + return E_NOTIMPL; +} + +static HRESULT WINAPI sample_CopyToBuffer(IMFSample *iface, IMFMediaBuffer *buffer) +{ + FIXME("%p, %p.\n", iface, buffer); + + return E_NOTIMPL; +} + +static const IMFSampleVtbl samplevtbl = +{ + sample_QueryInterface, + sample_AddRef, + sample_Release, + sample_GetItem, + sample_GetItemType, + sample_CompareItem, + sample_Compare, + sample_GetUINT32, + sample_GetUINT64, + sample_GetDouble, + sample_GetGUID, + sample_GetStringLength, + sample_GetString, + sample_GetAllocatedString, + sample_GetBlobSize, + sample_GetBlob, + sample_GetAllocatedBlob, + sample_GetUnknown, + sample_SetItem, + sample_DeleteItem, + sample_DeleteAllItems, + sample_SetUINT32, + sample_SetUINT64, + sample_SetDouble, + sample_SetGUID, + sample_SetString, + sample_SetBlob, + sample_SetUnknown, + sample_LockStore, + sample_UnlockStore, + sample_GetCount, + sample_GetItemByIndex, + sample_CopyAllItems, + sample_GetSampleFlags, + sample_SetSampleFlags, + sample_GetSampleTime, + sample_SetSampleTime, + sample_GetSampleDuration, + sample_SetSampleDuration, + sample_GetBufferCount, + sample_GetBufferByIndex, + sample_ConvertToContiguousBuffer, + sample_AddBuffer, + sample_RemoveBufferByIndex, + sample_RemoveAllBuffers, + sample_GetTotalLength, + sample_CopyToBuffer, +}; + +/*********************************************************************** + * MFCreateSample (mfplat.@) + */ +HRESULT WINAPI MFCreateSample(IMFSample **sample) +{ + struct sample *object; + + TRACE("%p.\n", sample); + + object = heap_alloc(sizeof(*object)); + if (!object) + return E_OUTOFMEMORY; + + init_attribute_object(&object->attributes, 0); + object->IMFSample_iface.lpVtbl = &samplevtbl; + + *sample = &object->IMFSample_iface; + + return S_OK; +} diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index 57943cf115..787c40c6b6 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -2798,450 +2798,6 @@ HRESULT WINAPI MFCreateEventQueue(IMFMediaEventQueue **queue) return S_OK; }
- -typedef struct _mfsample -{ - mfattributes attributes; - IMFSample IMFSample_iface; -} mfsample; - -static inline mfsample *impl_from_IMFSample(IMFSample *iface) -{ - return CONTAINING_RECORD(iface, mfsample, IMFSample_iface); -} - -static HRESULT WINAPI mfsample_QueryInterface(IMFSample *iface, REFIID riid, void **out) -{ - mfsample *This = impl_from_IMFSample(iface); - - TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), out); - - if(IsEqualGUID(riid, &IID_IUnknown) || - IsEqualGUID(riid, &IID_IMFAttributes) || - IsEqualGUID(riid, &IID_IMFSample)) - { - *out = &This->IMFSample_iface; - } - else - { - FIXME("(%s, %p)\n", debugstr_guid(riid), out); - *out = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*out); - return S_OK; -} - -static ULONG WINAPI mfsample_AddRef(IMFSample *iface) -{ - mfsample *This = impl_from_IMFSample(iface); - ULONG ref = InterlockedIncrement(&This->attributes.ref); - - TRACE("(%p) ref=%u\n", This, ref); - - return ref; -} - -static ULONG WINAPI mfsample_Release(IMFSample *iface) -{ - mfsample *This = impl_from_IMFSample(iface); - ULONG ref = InterlockedDecrement(&This->attributes.ref); - - TRACE("(%p) ref=%u\n", This, ref); - - if (!ref) - { - heap_free(This); - } - - return ref; -} - -static HRESULT WINAPI mfsample_GetItem(IMFSample *iface, REFGUID key, PROPVARIANT *value) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_GetItem(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mfsample_GetItemType(IMFSample *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_GetItemType(&This->attributes.IMFAttributes_iface, key, type); -} - -static HRESULT WINAPI mfsample_CompareItem(IMFSample *iface, REFGUID key, REFPROPVARIANT value, BOOL *result) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_CompareItem(&This->attributes.IMFAttributes_iface, key, value, result); -} - -static HRESULT WINAPI mfsample_Compare(IMFSample *iface, IMFAttributes *theirs, MF_ATTRIBUTES_MATCH_TYPE type, - BOOL *result) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_Compare(&This->attributes.IMFAttributes_iface, theirs, type, result); -} - -static HRESULT WINAPI mfsample_GetUINT32(IMFSample *iface, REFGUID key, UINT32 *value) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_GetUINT32(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mfsample_GetUINT64(IMFSample *iface, REFGUID key, UINT64 *value) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_GetUINT64(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mfsample_GetDouble(IMFSample *iface, REFGUID key, double *value) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_GetDouble(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mfsample_GetGUID(IMFSample *iface, REFGUID key, GUID *value) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_GetGUID(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mfsample_GetStringLength(IMFSample *iface, REFGUID key, UINT32 *length) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_GetStringLength(&This->attributes.IMFAttributes_iface, key, length); -} - -static HRESULT WINAPI mfsample_GetString(IMFSample *iface, REFGUID key, WCHAR *value, - UINT32 size, UINT32 *length) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_GetString(&This->attributes.IMFAttributes_iface, key, value, size, length); -} - -static HRESULT WINAPI mfsample_GetAllocatedString(IMFSample *iface, REFGUID key, - WCHAR **value, UINT32 *length) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_GetAllocatedString(&This->attributes.IMFAttributes_iface, key, value, length); -} - -static HRESULT WINAPI mfsample_GetBlobSize(IMFSample *iface, REFGUID key, UINT32 *size) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_GetBlobSize(&This->attributes.IMFAttributes_iface, key, size); -} - -static HRESULT WINAPI mfsample_GetBlob(IMFSample *iface, REFGUID key, UINT8 *buf, - UINT32 bufsize, UINT32 *blobsize) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_GetBlob(&This->attributes.IMFAttributes_iface, key, buf, bufsize, blobsize); -} - -static HRESULT WINAPI mfsample_GetAllocatedBlob(IMFSample *iface, REFGUID key, UINT8 **buf, UINT32 *size) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_GetAllocatedBlob(&This->attributes.IMFAttributes_iface, key, buf, size); -} - -static HRESULT WINAPI mfsample_GetUnknown(IMFSample *iface, REFGUID key, REFIID riid, void **ppv) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_GetUnknown(&This->attributes.IMFAttributes_iface, key, riid, ppv); -} - -static HRESULT WINAPI mfsample_SetItem(IMFSample *iface, REFGUID key, REFPROPVARIANT value) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_SetItem(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mfsample_DeleteItem(IMFSample *iface, REFGUID key) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_DeleteItem(&This->attributes.IMFAttributes_iface, key); -} - -static HRESULT WINAPI mfsample_DeleteAllItems(IMFSample *iface) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_DeleteAllItems(&This->attributes.IMFAttributes_iface); -} - -static HRESULT WINAPI mfsample_SetUINT32(IMFSample *iface, REFGUID key, UINT32 value) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_SetUINT32(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mfsample_SetUINT64(IMFSample *iface, REFGUID key, UINT64 value) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_SetUINT64(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mfsample_SetDouble(IMFSample *iface, REFGUID key, double value) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_SetDouble(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mfsample_SetGUID(IMFSample *iface, REFGUID key, REFGUID value) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_SetGUID(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mfsample_SetString(IMFSample *iface, REFGUID key, const WCHAR *value) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_SetString(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mfsample_SetBlob(IMFSample *iface, REFGUID key, const UINT8 *buf, UINT32 size) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_SetBlob(&This->attributes.IMFAttributes_iface, key, buf, size); -} - -static HRESULT WINAPI mfsample_SetUnknown(IMFSample *iface, REFGUID key, IUnknown *unknown) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_SetUnknown(&This->attributes.IMFAttributes_iface, key, unknown); -} - -static HRESULT WINAPI mfsample_LockStore(IMFSample *iface) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_LockStore(&This->attributes.IMFAttributes_iface); -} - -static HRESULT WINAPI mfsample_UnlockStore(IMFSample *iface) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_UnlockStore(&This->attributes.IMFAttributes_iface); -} - -static HRESULT WINAPI mfsample_GetCount(IMFSample *iface, UINT32 *items) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_GetCount(&This->attributes.IMFAttributes_iface, items); -} - -static HRESULT WINAPI mfsample_GetItemByIndex(IMFSample *iface, UINT32 index, GUID *key, PROPVARIANT *value) -{ - mfsample *This = impl_from_IMFSample(iface); - return IMFAttributes_GetItemByIndex(&This->attributes.IMFAttributes_iface, index, key, value); -} - -static HRESULT WINAPI mfsample_CopyAllItems(IMFSample *iface, IMFAttributes *dest) -{ - mfsample *This = impl_from_IMFSample(iface); - - FIXME("%p, %p\n", This, dest); - - return E_NOTIMPL; -} - -static HRESULT WINAPI mfsample_GetSampleFlags(IMFSample *iface, DWORD *flags) -{ - mfsample *This = impl_from_IMFSample(iface); - - FIXME("%p, %p\n", This, flags); - - return E_NOTIMPL; -} - -static HRESULT WINAPI mfsample_SetSampleFlags(IMFSample *iface, DWORD flags) -{ - mfsample *This = impl_from_IMFSample(iface); - - FIXME("%p, %x\n", This, flags); - - return E_NOTIMPL; -} - -static HRESULT WINAPI mfsample_GetSampleTime(IMFSample *iface, LONGLONG *sampletime) -{ - mfsample *This = impl_from_IMFSample(iface); - - FIXME("%p, %p\n", This, sampletime); - - return E_NOTIMPL; -} - -static HRESULT WINAPI mfsample_SetSampleTime(IMFSample *iface, LONGLONG sampletime) -{ - mfsample *This = impl_from_IMFSample(iface); - - FIXME("%p, %s\n", This, wine_dbgstr_longlong(sampletime)); - - return E_NOTIMPL; -} - -static HRESULT WINAPI mfsample_GetSampleDuration(IMFSample *iface, LONGLONG *duration) -{ - mfsample *This = impl_from_IMFSample(iface); - - FIXME("%p, %p\n", This, duration); - - return E_NOTIMPL; -} - -static HRESULT WINAPI mfsample_SetSampleDuration(IMFSample *iface, LONGLONG duration) -{ - mfsample *This = impl_from_IMFSample(iface); - - FIXME("%p, %s\n", This, wine_dbgstr_longlong(duration)); - - return E_NOTIMPL; -} - -static HRESULT WINAPI mfsample_GetBufferCount(IMFSample *iface, DWORD *count) -{ - mfsample *This = impl_from_IMFSample(iface); - - FIXME("%p, %p\n", This, count); - - if(*count) - *count = 0; - - return S_OK; -} - -static HRESULT WINAPI mfsample_GetBufferByIndex(IMFSample *iface, DWORD index, IMFMediaBuffer **buffer) -{ - mfsample *This = impl_from_IMFSample(iface); - - FIXME("%p, %u, %p\n", This, index, buffer); - - return E_NOTIMPL; -} - -static HRESULT WINAPI mfsample_ConvertToContiguousBuffer(IMFSample *iface, IMFMediaBuffer **buffer) -{ - mfsample *This = impl_from_IMFSample(iface); - - FIXME("%p, %p\n", This, buffer); - - return E_NOTIMPL; -} - -static HRESULT WINAPI mfsample_AddBuffer(IMFSample *iface, IMFMediaBuffer *buffer) -{ - mfsample *This = impl_from_IMFSample(iface); - - FIXME("%p, %p\n", This, buffer); - - return E_NOTIMPL; -} - -static HRESULT WINAPI mfsample_RemoveBufferByIndex(IMFSample *iface, DWORD index) -{ - mfsample *This = impl_from_IMFSample(iface); - - FIXME("%p, %u\n", This, index); - - return E_NOTIMPL; -} - -static HRESULT WINAPI mfsample_RemoveAllBuffers(IMFSample *iface) -{ - mfsample *This = impl_from_IMFSample(iface); - - FIXME("%p\n", This); - - return E_NOTIMPL; -} - -static HRESULT WINAPI mfsample_GetTotalLength(IMFSample *iface, DWORD *length) -{ - mfsample *This = impl_from_IMFSample(iface); - - FIXME("%p, %p\n", This, length); - - return E_NOTIMPL; -} - -static HRESULT WINAPI mfsample_CopyToBuffer(IMFSample *iface, IMFMediaBuffer *buffer) -{ - mfsample *This = impl_from_IMFSample(iface); - - FIXME("%p, %p\n", This, buffer); - - return E_NOTIMPL; -} - -static const IMFSampleVtbl mfsample_vtbl = -{ - mfsample_QueryInterface, - mfsample_AddRef, - mfsample_Release, - mfsample_GetItem, - mfsample_GetItemType, - mfsample_CompareItem, - mfsample_Compare, - mfsample_GetUINT32, - mfsample_GetUINT64, - mfsample_GetDouble, - mfsample_GetGUID, - mfsample_GetStringLength, - mfsample_GetString, - mfsample_GetAllocatedString, - mfsample_GetBlobSize, - mfsample_GetBlob, - mfsample_GetAllocatedBlob, - mfsample_GetUnknown, - mfsample_SetItem, - mfsample_DeleteItem, - mfsample_DeleteAllItems, - mfsample_SetUINT32, - mfsample_SetUINT64, - mfsample_SetDouble, - mfsample_SetGUID, - mfsample_SetString, - mfsample_SetBlob, - mfsample_SetUnknown, - mfsample_LockStore, - mfsample_UnlockStore, - mfsample_GetCount, - mfsample_GetItemByIndex, - mfsample_CopyAllItems, - mfsample_GetSampleFlags, - mfsample_SetSampleFlags, - mfsample_GetSampleTime, - mfsample_SetSampleTime, - mfsample_GetSampleDuration, - mfsample_SetSampleDuration, - mfsample_GetBufferCount, - mfsample_GetBufferByIndex, - mfsample_ConvertToContiguousBuffer, - mfsample_AddBuffer, - mfsample_RemoveBufferByIndex, - mfsample_RemoveAllBuffers, - mfsample_GetTotalLength, - mfsample_CopyToBuffer -}; - -HRESULT WINAPI MFCreateSample(IMFSample **sample) -{ - mfsample *object; - - TRACE("%p\n", sample); - - object = heap_alloc(sizeof(*object)); - if(!object) - return E_OUTOFMEMORY; - - init_attribute_object(&object->attributes, 0); - object->IMFSample_iface.lpVtbl = &mfsample_vtbl; - *sample = &object->IMFSample_iface; - - return S_OK; -} - struct collection { IMFCollection IMFCollection_iface;
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/buffer.c | 127 ++++++++++++++++++++++++++++++----- dlls/mfplat/main.c | 28 -------- dlls/mfplat/mediatype.c | 1 - dlls/mfplat/mfplat_private.h | 29 ++++++++ dlls/mfplat/queue.c | 1 - dlls/mfplat/tests/mfplat.c | 74 +++++++++++++++++++- 6 files changed, 209 insertions(+), 51 deletions(-)
diff --git a/dlls/mfplat/buffer.c b/dlls/mfplat/buffer.c index f60c015c6c..833ec041a9 100644 --- a/dlls/mfplat/buffer.c +++ b/dlls/mfplat/buffer.c @@ -21,7 +21,6 @@ #include "mfplat_private.h"
#include "wine/debug.h" -#include "wine/heap.h"
WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
@@ -39,6 +38,12 @@ struct sample { struct attributes attributes; IMFSample IMFSample_iface; + + IMFMediaBuffer **buffers; + size_t buffer_count; + size_t capacity; + DWORD flags; + CRITICAL_SECTION cs; };
static inline struct memory_buffer *impl_from_IMFMediaBuffer(IMFMediaBuffer *iface) @@ -258,11 +263,16 @@ static ULONG WINAPI sample_Release(IMFSample *iface) { struct sample *sample = impl_from_IMFSample(iface); ULONG refcount = InterlockedDecrement(&sample->attributes.ref); + size_t i;
TRACE("%p, refcount %u.\n", iface, refcount);
if (!refcount) { + for (i = 0; i < sample->buffer_count; ++i) + IMFMediaBuffer_Release(sample->buffers[i]); + DeleteCriticalSection(&sample->cs); + heap_free(sample->buffers); heap_free(sample); }
@@ -453,9 +463,15 @@ static HRESULT WINAPI sample_CopyAllItems(IMFSample *iface, IMFAttributes *dest)
static HRESULT WINAPI sample_GetSampleFlags(IMFSample *iface, DWORD *flags) { - FIXME("%p, %p.\n", iface, flags); + struct sample *sample = impl_from_IMFSample(iface);
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, flags); + + EnterCriticalSection(&sample->cs); + *flags = sample->flags; + LeaveCriticalSection(&sample->cs); + + return S_OK; }
static HRESULT WINAPI sample_SetSampleFlags(IMFSample *iface, DWORD flags) @@ -495,19 +511,38 @@ static HRESULT WINAPI sample_SetSampleDuration(IMFSample *iface, LONGLONG durati
static HRESULT WINAPI sample_GetBufferCount(IMFSample *iface, DWORD *count) { - FIXME("%p, %p.\n", iface, count); + struct sample *sample = impl_from_IMFSample(iface); + + TRACE("%p, %p.\n", iface, count); + + if (!count) + return E_INVALIDARG;
- if (*count) - *count = 0; + EnterCriticalSection(&sample->cs); + *count = sample->buffer_count; + EnterCriticalSection(&sample->cs);
return S_OK; }
static HRESULT WINAPI sample_GetBufferByIndex(IMFSample *iface, DWORD index, IMFMediaBuffer **buffer) { - FIXME("%p, %u, %p.\n", iface, index, buffer); + struct sample *sample = impl_from_IMFSample(iface); + HRESULT hr = S_OK;
- return E_NOTIMPL; + TRACE("%p, %u, %p.\n", iface, index, buffer); + + EnterCriticalSection(&sample->cs); + if (index < sample->buffer_count) + { + *buffer = sample->buffers[index]; + IMFMediaBuffer_AddRef(*buffer); + } + else + hr = E_INVALIDARG; + LeaveCriticalSection(&sample->cs); + + return hr; }
static HRESULT WINAPI sample_ConvertToContiguousBuffer(IMFSample *iface, IMFMediaBuffer **buffer) @@ -519,30 +554,85 @@ static HRESULT WINAPI sample_ConvertToContiguousBuffer(IMFSample *iface, IMFMedi
static HRESULT WINAPI sample_AddBuffer(IMFSample *iface, IMFMediaBuffer *buffer) { - FIXME("%p, %p.\n", iface, buffer); + struct sample *sample = impl_from_IMFSample(iface); + HRESULT hr = S_OK;
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, buffer); + + EnterCriticalSection(&sample->cs); + if (!mf_array_reserve((void **)&sample->buffers, &sample->capacity, sample->buffer_count + 1, + sizeof(*sample->buffers))) + hr = E_OUTOFMEMORY; + else + { + sample->buffers[sample->buffer_count++] = buffer; + IMFMediaBuffer_AddRef(buffer); + } + LeaveCriticalSection(&sample->cs); + + return hr; }
static HRESULT WINAPI sample_RemoveBufferByIndex(IMFSample *iface, DWORD index) { - FIXME("%p, %u.\n", iface, index); + struct sample *sample = impl_from_IMFSample(iface); + HRESULT hr = S_OK;
- return E_NOTIMPL; + TRACE("%p, %u.\n", iface, index); + + EnterCriticalSection(&sample->cs); + if (index < sample->buffer_count) + { + IMFMediaBuffer_Release(sample->buffers[index]); + if (index < sample->buffer_count - 1) + { + memmove(&sample->buffers[index], &sample->buffers[index+1], + (sample->buffer_count - index - 1) * sizeof(*sample->buffers)); + } + sample->buffer_count--; + } + else + hr = E_INVALIDARG; + LeaveCriticalSection(&sample->cs); + + return hr; }
static HRESULT WINAPI sample_RemoveAllBuffers(IMFSample *iface) { - FIXME("%p.\n", iface); + struct sample *sample = impl_from_IMFSample(iface); + size_t i;
- return E_NOTIMPL; + TRACE("%p.\n", iface); + + EnterCriticalSection(&sample->cs); + for (i = 0; i < sample->buffer_count; ++i) + IMFMediaBuffer_Release(sample->buffers[i]); + sample->buffer_count = 0; + LeaveCriticalSection(&sample->cs); + + return S_OK; }
-static HRESULT WINAPI sample_GetTotalLength(IMFSample *iface, DWORD *length) +static HRESULT WINAPI sample_GetTotalLength(IMFSample *iface, DWORD *total_length) { - FIXME("%p, %p.\n", iface, length); + struct sample *sample = impl_from_IMFSample(iface); + DWORD length; + size_t i;
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, total_length); + + *total_length = 0; + + EnterCriticalSection(&sample->cs); + for (i = 0; i < sample->buffer_count; ++i) + { + if (SUCCEEDED(IMFMediaBuffer_GetCurrentLength(sample->buffers[i], &length))) + *total_length += length; + } + LeaveCriticalSection(&sample->cs); + + return S_OK; }
static HRESULT WINAPI sample_CopyToBuffer(IMFSample *iface, IMFMediaBuffer *buffer) @@ -612,12 +702,13 @@ HRESULT WINAPI MFCreateSample(IMFSample **sample)
TRACE("%p.\n", sample);
- object = heap_alloc(sizeof(*object)); + object = heap_alloc_zero(sizeof(*object)); if (!object) return E_OUTOFMEMORY;
init_attribute_object(&object->attributes, 0); object->IMFSample_iface.lpVtbl = &samplevtbl; + InitializeCriticalSection(&object->cs);
*sample = &object->IMFSample_iface;
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index 787c40c6b6..2d7e02e473 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -29,7 +29,6 @@
#include "initguid.h"
-#include "wine/heap.h" #include "wine/debug.h" #include "wine/unicode.h" #include "wine/list.h" @@ -129,33 +128,6 @@ static BOOL GUIDFromString(LPCWSTR s, GUID *id) return FALSE; }
-static BOOL mf_array_reserve(void **elements, size_t *capacity, size_t count, size_t size) -{ - size_t new_capacity, max_capacity; - void *new_elements; - - if (count <= *capacity) - return TRUE; - - max_capacity = ~(SIZE_T)0 / size; - if (count > max_capacity) - return FALSE; - - new_capacity = max(4, *capacity); - while (new_capacity < count && new_capacity <= max_capacity / 2) - new_capacity *= 2; - if (new_capacity < count) - new_capacity = max_capacity; - - if (!(new_elements = heap_realloc(*elements, new_capacity * size))) - return FALSE; - - *elements = new_elements; - *capacity = new_capacity; - - return TRUE; -} - BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { switch (reason) diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index 195ab38da5..7abbf31796 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -21,7 +21,6 @@ #include "mfplat_private.h"
#include "wine/debug.h" -#include "wine/heap.h"
WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
diff --git a/dlls/mfplat/mfplat_private.h b/dlls/mfplat/mfplat_private.h index e5b0647e63..72f8f684f6 100644 --- a/dlls/mfplat/mfplat_private.h +++ b/dlls/mfplat/mfplat_private.h @@ -20,6 +20,8 @@ #include "mfidl.h" #include "mferror.h"
+#include "wine/heap.h" + typedef struct attributes { IMFAttributes IMFAttributes_iface; @@ -31,3 +33,30 @@ extern void init_attribute_object(mfattributes *object, UINT32 size) DECLSPEC_HI extern void init_system_queues(void) DECLSPEC_HIDDEN; extern void shutdown_system_queues(void) DECLSPEC_HIDDEN; extern BOOL is_platform_locked(void) DECLSPEC_HIDDEN; + +static inline BOOL mf_array_reserve(void **elements, size_t *capacity, size_t count, size_t size) +{ + size_t new_capacity, max_capacity; + void *new_elements; + + if (count <= *capacity) + return TRUE; + + max_capacity = ~(SIZE_T)0 / size; + if (count > max_capacity) + return FALSE; + + new_capacity = max(4, *capacity); + while (new_capacity < count && new_capacity <= max_capacity / 2) + new_capacity *= 2; + if (new_capacity < count) + new_capacity = max_capacity; + + if (!(new_elements = heap_realloc(*elements, new_capacity * size))) + return FALSE; + + *elements = new_elements; + *capacity = new_capacity; + + return TRUE; +} diff --git a/dlls/mfplat/queue.c b/dlls/mfplat/queue.c index 4d3322840c..1b9ef38a4e 100644 --- a/dlls/mfplat/queue.c +++ b/dlls/mfplat/queue.c @@ -21,7 +21,6 @@ #define COBJMACROS
#include "wine/debug.h" -#include "wine/heap.h" #include "wine/list.h"
#include "mfplat_private.h" diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 674bcf418e..19ec6ec6d1 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -714,19 +714,87 @@ static void test_system_memory_buffer(void) IMFMediaBuffer_Release(buffer); }
-static void test_MFSample(void) +static void test_sample(void) { + IMFMediaBuffer *buffer, *buffer2; + DWORD count, flags, length; IMFSample *sample; + LONGLONG time; HRESULT hr; - UINT32 count;
hr = MFCreateSample( &sample ); ok(hr == S_OK, "got 0x%08x\n", hr);
+ hr = IMFSample_GetBufferCount(sample, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + hr = IMFSample_GetBufferCount(sample, &count); ok(hr == S_OK, "got 0x%08x\n", hr); ok(count == 0, "got %d\n", count);
+ hr = IMFSample_GetSampleFlags(sample, &flags); + ok(hr == S_OK, "Failed to get sample flags, hr %#x.\n", hr); + ok(!flags, "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); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + hr = IMFSample_RemoveBufferByIndex(sample, 0); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + hr = IMFSample_RemoveAllBuffers(sample); + ok(hr == S_OK, "Failed to remove all, hr %#x.\n", hr); + + hr = IMFSample_GetTotalLength(sample, &length); + ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr); + ok(!length, "Unexpected total length %u.\n", length); + + hr = MFCreateMemoryBuffer(16, &buffer); + ok(hr == S_OK, "Failed to create buffer, hr %#x.\n", hr); + + hr = IMFSample_AddBuffer(sample, buffer); + ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr); + + hr = IMFSample_AddBuffer(sample, buffer); + ok(hr == S_OK, "Failed to add buffer, hr %#x.\n", hr); + + hr = IMFSample_GetBufferCount(sample, &count); + ok(hr == S_OK, "Failed to get buffer count, hr %#x.\n", hr); + ok(count == 2, "Unexpected buffer count %u.\n", count); + + hr = IMFSample_GetBufferByIndex(sample, 0, &buffer2); + ok(hr == S_OK, "Failed to get buffer, hr %#x.\n", hr); + ok(buffer2 == buffer, "Unexpected object.\n"); + IMFMediaBuffer_Release(buffer2); + + hr = IMFSample_GetTotalLength(sample, &length); + ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr); + ok(!length, "Unexpected total length %u.\n", length); + + hr = IMFMediaBuffer_SetCurrentLength(buffer, 2); + ok(hr == S_OK, "Failed to set current length, hr %#x.\n", hr); + + hr = IMFSample_GetTotalLength(sample, &length); + ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr); + ok(length == 4, "Unexpected total length %u.\n", length); + + hr = IMFSample_RemoveBufferByIndex(sample, 1); + ok(hr == S_OK, "Failed to remove buffer, hr %#x.\n", hr); + + hr = IMFSample_GetTotalLength(sample, &length); + ok(hr == S_OK, "Failed to get total length, hr %#x.\n", hr); + ok(length == 2, "Unexpected total length %u.\n", length); + + IMFMediaBuffer_Release(buffer); + IMFSample_Release(sample); }
@@ -1541,7 +1609,7 @@ START_TEST(mfplat) test_MFCreateMediaType(); test_MFCreateMediaEvent(); test_MFCreateAttributes(); - test_MFSample(); + test_sample(); test_MFCreateFile(); test_MFCreateMFByteStreamOnStream(); test_system_memory_buffer();