Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/buffer.c | 89 +++++++++++++++++++++++++++++++++++--- dlls/mfplat/mfplat.spec | 1 + dlls/mfplat/tests/mfplat.c | 37 ++++++++++++++++ include/mfidl.idl | 1 + 4 files changed, 122 insertions(+), 6 deletions(-)
diff --git a/dlls/mfplat/buffer.c b/dlls/mfplat/buffer.c index 1a31299d244..67c60663b33 100644 --- a/dlls/mfplat/buffer.c +++ b/dlls/mfplat/buffer.c @@ -62,6 +62,7 @@ struct sample { struct attributes attributes; IMFSample IMFSample_iface; + IMFTrackedSample IMFTrackedSample_iface;
IMFMediaBuffer **buffers; size_t buffer_count; @@ -87,6 +88,11 @@ static inline struct sample *impl_from_IMFSample(IMFSample *iface) return CONTAINING_RECORD(iface, struct sample, IMFSample_iface); }
+static struct sample *impl_from_IMFTrackedSample(IMFTrackedSample *iface) +{ + return CONTAINING_RECORD(iface, struct sample, IMFTrackedSample_iface); +} + static HRESULT WINAPI memory_buffer_QueryInterface(IMFMediaBuffer *iface, REFIID riid, void **out) { struct memory_buffer *buffer = impl_from_IMFMediaBuffer(iface); @@ -711,20 +717,29 @@ HRESULT WINAPI MFCreateMediaBufferFromMediaType(IMFMediaType *media_type, LONGLO
static HRESULT WINAPI sample_QueryInterface(IMFSample *iface, REFIID riid, void **out) { + struct sample *sample = impl_from_IMFSample(iface); + 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; + *out = &sample->IMFSample_iface; + } + else if (sample->IMFTrackedSample_iface.lpVtbl && IsEqualIID(riid, &IID_IMFTrackedSample)) + { + *out = &sample->IMFTrackedSample_iface; + } + else + { + WARN("Unsupported %s.\n", debugstr_guid(riid)); + *out = NULL; + return E_NOINTERFACE; }
- WARN("Unsupported %s.\n", debugstr_guid(riid)); - *out = NULL; - return E_NOINTERFACE; + IUnknown_AddRef((IUnknown *)*out); + return S_OK; }
static ULONG WINAPI sample_AddRef(IMFSample *iface) @@ -1448,6 +1463,40 @@ static const IMFSampleVtbl samplevtbl = sample_CopyToBuffer, };
+static HRESULT WINAPI tracked_sample_QueryInterface(IMFTrackedSample *iface, REFIID riid, void **obj) +{ + struct sample *sample = impl_from_IMFTrackedSample(iface); + return IMFSample_QueryInterface(&sample->IMFSample_iface, riid, obj); +} + +static ULONG WINAPI tracked_sample_AddRef(IMFTrackedSample *iface) +{ + struct sample *sample = impl_from_IMFTrackedSample(iface); + return IMFSample_AddRef(&sample->IMFSample_iface); +} + +static ULONG WINAPI tracked_sample_Release(IMFTrackedSample *iface) +{ + struct sample *sample = impl_from_IMFTrackedSample(iface); + return IMFSample_Release(&sample->IMFSample_iface); +} + +static HRESULT WINAPI tracked_sample_SetAllocator(IMFTrackedSample *iface, + IMFAsyncCallback *sample_allocator, IUnknown *state) +{ + FIXME("%p, %p, %p.\n", iface, sample_allocator, state); + + return E_NOTIMPL; +} + +static const IMFTrackedSampleVtbl tracked_sample_vtbl = +{ + tracked_sample_QueryInterface, + tracked_sample_AddRef, + tracked_sample_Release, + tracked_sample_SetAllocator, +}; + /*********************************************************************** * MFCreateSample (mfplat.@) */ @@ -1476,3 +1525,31 @@ HRESULT WINAPI MFCreateSample(IMFSample **sample)
return S_OK; } + +/*********************************************************************** + * MFCreateTrackedSample (mfplat.@) + */ +HRESULT WINAPI MFCreateTrackedSample(IMFTrackedSample **sample) +{ + struct sample *object; + HRESULT hr; + + TRACE("%p.\n", sample); + + object = heap_alloc_zero(sizeof(*object)); + if (!object) + return E_OUTOFMEMORY; + + if (FAILED(hr = init_attributes_object(&object->attributes, 0))) + { + heap_free(object); + return hr; + } + + object->IMFSample_iface.lpVtbl = &samplevtbl; + object->IMFTrackedSample_iface.lpVtbl = &tracked_sample_vtbl; + + *sample = &object->IMFTrackedSample_iface; + + return S_OK; +} diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec index 16be972e5bd..f55a8237d35 100644 --- a/dlls/mfplat/mfplat.spec +++ b/dlls/mfplat/mfplat.spec @@ -70,6 +70,7 @@ @ stdcall MFCreateSystemTimeSource(ptr) @ stub MFCreateSystemUnderlyingClock @ stub MFCreateTempFile +@ stdcall MFCreateTrackedSample(ptr) @ stdcall MFCreateTransformActivate(ptr) @ stub MFCreateURLFromPath @ stub MFCreateUdpSockets diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 8b4012f8087..01749dd9ef8 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -107,6 +107,7 @@ static HRESULT (WINAPI *pMFCreate2DMediaBuffer)(DWORD width, DWORD height, DWORD static HRESULT (WINAPI *pMFCreateMediaBufferFromMediaType)(IMFMediaType *media_type, LONGLONG duration, DWORD min_length, DWORD min_alignment, IMFMediaBuffer **buffer); static HRESULT (WINAPI *pMFCreateDXSurfaceBuffer)(REFIID riid, IUnknown *surface, BOOL bottom_up, IMFMediaBuffer **buffer); +static HRESULT (WINAPI *pMFCreateTrackedSample)(IMFTrackedSample **sample);
static HWND create_window(void) { @@ -715,6 +716,7 @@ static void init_functions(void) X(MFCreateSourceResolver); X(MFCreateMediaBufferFromMediaType); X(MFCreateMFByteStreamOnStream); + X(MFCreateTrackedSample); X(MFCreateTransformActivate); X(MFGetPlaneSize); X(MFGetStrideForBitmapInfoHeader); @@ -5465,6 +5467,40 @@ done: DestroyWindow(window); }
+static void test_MFCreateTrackedSample(void) +{ + IMFTrackedSample *tracked_sample; + IMFDesiredSample *desired_sample; + IMFSample *sample; + IUnknown *unk; + HRESULT hr; + + if (!pMFCreateTrackedSample) + { + win_skip("MFCreateTrackedSample() is not available.\n"); + return; + } + + hr = pMFCreateTrackedSample(&tracked_sample); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + /* It's actually a sample. */ + hr = IMFTrackedSample_QueryInterface(tracked_sample, &IID_IMFSample, (void **)&sample); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFTrackedSample_QueryInterface(tracked_sample, &IID_IUnknown, (void **)&unk); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(unk == (IUnknown *)sample, "Unexpected pointer.\n"); + IUnknown_Release(unk); + + IMFSample_Release(sample); + + hr = IMFTrackedSample_QueryInterface(tracked_sample, &IID_IMFDesiredSample, (void **)&desired_sample); + ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr); + + IMFTrackedSample_Release(tracked_sample); +} + START_TEST(mfplat) { char **argv; @@ -5522,6 +5558,7 @@ START_TEST(mfplat) test_MFInitMediaTypeFromWaveFormatEx(); test_MFCreateMFVideoFormatFromMFMediaType(); test_MFCreateDXSurfaceBuffer(); + test_MFCreateTrackedSample();
CoUninitialize(); } diff --git a/include/mfidl.idl b/include/mfidl.idl index 1f5fc06dd1e..4ceeb707bd0 100644 --- a/include/mfidl.idl +++ b/include/mfidl.idl @@ -648,6 +648,7 @@ cpp_quote("HRESULT WINAPI MFGetService(IUnknown *object, REFGUID service, REFIID cpp_quote("MFTIME WINAPI MFGetSystemTime(void);") cpp_quote("HRESULT WINAPI MFGetTopoNodeCurrentType(IMFTopologyNode *node, DWORD stream, BOOL output, IMFMediaType **type);") cpp_quote("HRESULT WINAPI MFShutdownObject(IUnknown *object);") +cpp_quote("HRESULT WINAPI MFCreateTrackedSample(IMFTrackedSample **sample);")
typedef enum _MFMEDIASOURCE_CHARACTERISTICS {