From 64eced491d87ea9d167ea73806568c31271a7fe3 Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Mon, 25 Feb 2019 11:33:55 +0300 Subject: [PATCH] mfreadwrite: Add sink writer stub. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/mfreadwrite/main.c | 219 +++++++++++++++++++++++++++++- dlls/mfreadwrite/mfreadwrite.spec | 2 +- include/mfidl.idl | 23 ++++ include/mfreadwrite.idl | 2 + 4 files changed, 241 insertions(+), 5 deletions(-) diff --git a/dlls/mfreadwrite/main.c b/dlls/mfreadwrite/main.c index dcacd9a7513..a83ece03596 100644 --- a/dlls/mfreadwrite/main.c +++ b/dlls/mfreadwrite/main.c @@ -27,8 +27,8 @@ #include "initguid.h" #include "ole2.h" #include "rpcproxy.h" -#include "mfreadwrite.h" #include "mfidl.h" +#include "mfreadwrite.h" #include "wine/debug.h" #include "wine/heap.h" @@ -77,11 +77,22 @@ typedef struct _srcreader LONG ref; } srcreader; +struct sink_writer +{ + IMFSinkWriter IMFSinkWriter_iface; + LONG refcount; +}; + static inline srcreader *impl_from_IMFSourceReader(IMFSourceReader *iface) { return CONTAINING_RECORD(iface, srcreader, IMFSourceReader_iface); } +static inline struct sink_writer *impl_from_IMFSinkWriter(IMFSinkWriter *iface) +{ + return CONTAINING_RECORD(iface, struct sink_writer, IMFSinkWriter_iface); +} + static HRESULT WINAPI src_reader_QueryInterface(IMFSourceReader *iface, REFIID riid, void **out) { srcreader *This = impl_from_IMFSourceReader(iface); @@ -249,6 +260,191 @@ static HRESULT create_source_reader_from_stream(IMFByteStream *stream, IMFAttrib return create_source_reader_from_source(NULL, attributes, riid, out); } +static HRESULT WINAPI sink_writer_QueryInterface(IMFSinkWriter *iface, REFIID riid, void **out) +{ + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out); + + if (IsEqualIID(riid, &IID_IMFSinkWriter) || + IsEqualIID(riid, &IID_IUnknown)) + { + *out = iface; + IMFSinkWriter_AddRef(iface); + return S_OK; + } + + WARN("Unsupported %s.\n", debugstr_guid(riid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI sink_writer_AddRef(IMFSinkWriter *iface) +{ + struct sink_writer *writer = impl_from_IMFSinkWriter(iface); + ULONG refcount = InterlockedIncrement(&writer->refcount); + + TRACE("%p, %u.\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI sink_writer_Release(IMFSinkWriter *iface) +{ + struct sink_writer *writer = impl_from_IMFSinkWriter(iface); + ULONG refcount = InterlockedDecrement(&writer->refcount); + + TRACE("%p, %u.\n", iface, refcount); + + if (!refcount) + { + heap_free(writer); + } + + return refcount; +} + +static HRESULT WINAPI sink_writer_AddStream(IMFSinkWriter *iface, IMFMediaType *type, DWORD *index) +{ + FIXME("%p, %p, %p.\n", iface, type, index); + + return E_NOTIMPL; +} + +static HRESULT WINAPI sink_writer_SetInputMediaType(IMFSinkWriter *iface, DWORD index, IMFMediaType *type, + IMFAttributes *parameters) +{ + FIXME("%p, %u, %p, %p.\n", iface, index, type, parameters); + + return E_NOTIMPL; +} + +static HRESULT WINAPI sink_writer_BeginWriting(IMFSinkWriter *iface) +{ + FIXME("%p.\n", iface); + + return E_NOTIMPL; +} + +static HRESULT WINAPI sink_writer_WriteSample(IMFSinkWriter *iface, DWORD index, IMFSample *sample) +{ + FIXME("%p, %u, %p.\n", iface, index, sample); + + return E_NOTIMPL; +} + +static HRESULT WINAPI sink_writer_SendStreamTick(IMFSinkWriter *iface, DWORD index, LONGLONG timestamp) +{ + FIXME("%p, %u, %s.\n", iface, index, wine_dbgstr_longlong(timestamp)); + + return E_NOTIMPL; +} + +static HRESULT WINAPI sink_writer_PlaceMarker(IMFSinkWriter *iface, DWORD index, void *context) +{ + FIXME("%p, %u, %p.\n", iface, index, context); + + return E_NOTIMPL; +} + +static HRESULT WINAPI sink_writer_NotifyEndOfSegment(IMFSinkWriter *iface, DWORD index) +{ + FIXME("%p, %u.\n", iface, index); + + return E_NOTIMPL; +} + +static HRESULT WINAPI sink_writer_Flush(IMFSinkWriter *iface, DWORD index) +{ + FIXME("%p, %u.\n", iface, index); + + return E_NOTIMPL; +} + +static HRESULT WINAPI sink_writer_Finalize(IMFSinkWriter *iface) +{ + FIXME("%p.\n", iface); + + return E_NOTIMPL; +} + +static HRESULT WINAPI sink_writer_GetServiceForStream(IMFSinkWriter *iface, DWORD index, REFGUID service, + REFIID riid, void **object) +{ + FIXME("%p, %u, %s, %s, %p.\n", iface, index, debugstr_guid(service), debugstr_guid(riid), object); + + return E_NOTIMPL; +} + +static HRESULT WINAPI sink_writer_GetStatistics(IMFSinkWriter *iface, DWORD index, MF_SINK_WRITER_STATISTICS *stats) +{ + FIXME("%p, %u, %p.\n", iface, index, stats); + + return E_NOTIMPL; +} + +static const IMFSinkWriterVtbl sink_writer_vtbl = +{ + sink_writer_QueryInterface, + sink_writer_AddRef, + sink_writer_Release, + sink_writer_AddStream, + sink_writer_SetInputMediaType, + sink_writer_BeginWriting, + sink_writer_WriteSample, + sink_writer_SendStreamTick, + sink_writer_PlaceMarker, + sink_writer_NotifyEndOfSegment, + sink_writer_Flush, + sink_writer_Finalize, + sink_writer_GetServiceForStream, + sink_writer_GetStatistics, +}; + +static HRESULT create_sink_writer_from_sink(IMFMediaSink *sink, IMFAttributes *attributes, + REFIID riid, void **out) +{ + struct sink_writer *object; + HRESULT hr; + + object = heap_alloc(sizeof(*object)); + if (!object) + return E_OUTOFMEMORY; + + object->IMFSinkWriter_iface.lpVtbl = &sink_writer_vtbl; + object->refcount = 1; + + hr = IMFSinkWriter_QueryInterface(&object->IMFSinkWriter_iface, riid, out); + IMFSinkWriter_Release(&object->IMFSinkWriter_iface); + return hr; +} + +static HRESULT create_sink_writer_from_stream(IMFByteStream *stream, IMFAttributes *attributes, + REFIID riid, void **out) +{ + struct sink_writer *object; + HRESULT hr; + + object = heap_alloc(sizeof(*object)); + if (!object) + return E_OUTOFMEMORY; + + object->IMFSinkWriter_iface.lpVtbl = &sink_writer_vtbl; + object->refcount = 1; + + hr = IMFSinkWriter_QueryInterface(&object->IMFSinkWriter_iface, riid, out); + IMFSinkWriter_Release(&object->IMFSinkWriter_iface); + return hr; +} + +/*********************************************************************** + * MFCreateSinkWriterFromMediaSink (mfreadwrite.@) + */ +HRESULT WINAPI MFCreateSinkWriterFromMediaSink(IMFMediaSink *sink, IMFAttributes *attributes, IMFSinkWriter **writer) +{ + TRACE("%p, %p, %p.\n", sink, attributes, writer); + + return create_sink_writer_from_sink(sink, attributes, &IID_IMFSinkWriter, (void **)writer); +} + /*********************************************************************** * MFCreateSourceReaderFromByteStream (mfreadwrite.@) */ @@ -334,9 +530,24 @@ static HRESULT WINAPI readwrite_factory_CreateInstanceFromObject(IMFReadWriteCla } else if (IsEqualGUID(clsid, &CLSID_MFSinkWriter)) { - FIXME("MFSinkWriter is not supported.\n"); - *out = NULL; - return E_NOTIMPL; + IMFByteStream *stream = NULL; + IMFMediaSink *sink = NULL; + + hr = IUnknown_QueryInterface(unk, &IID_IMFByteStream, (void **)&stream); + if (FAILED(hr)) + hr = IUnknown_QueryInterface(unk, &IID_IMFMediaSink, (void **)&sink); + + if (stream) + hr = create_sink_writer_from_stream(stream, attributes, riid, out); + else if (sink) + hr = create_sink_writer_from_sink(sink, attributes, riid, out); + + if (sink) + IMFMediaSink_Release(sink); + if (stream) + IMFByteStream_Release(stream); + + return hr; } else { diff --git a/dlls/mfreadwrite/mfreadwrite.spec b/dlls/mfreadwrite/mfreadwrite.spec index ad616467188..d8ed6942eb0 100644 --- a/dlls/mfreadwrite/mfreadwrite.spec +++ b/dlls/mfreadwrite/mfreadwrite.spec @@ -2,7 +2,7 @@ @ stdcall -private DllGetClassObject(ptr ptr ptr) @ stdcall -private DllRegisterServer() @ stdcall -private DllUnregisterServer() -@ stub MFCreateSinkWriterFromMediaSink +@ stdcall MFCreateSinkWriterFromMediaSink(ptr ptr ptr) @ stub MFCreateSinkWriterFromURL @ stdcall MFCreateSourceReaderFromByteStream(ptr ptr ptr) @ stdcall MFCreateSourceReaderFromMediaSource(ptr ptr ptr) diff --git a/include/mfidl.idl b/include/mfidl.idl index 831bc357df1..c8f011bb777 100644 --- a/include/mfidl.idl +++ b/include/mfidl.idl @@ -357,6 +357,29 @@ interface IMFMediaSource : IMFMediaEventGenerator HRESULT Shutdown(); } +interface IMFStreamSink; +interface IMFPresentationClock; + +[ + object, + uuid(6ef2a660-47c0-4666-b13d-cbb717f2fa2c) +] +interface IMFMediaSink : IUnknown +{ + HRESULT GetCharacteristics([out] DWORD *characteristics); + HRESULT AddStreamSink( + [in] DWORD stream_sink_id, + [in] IMFMediaType *media_type, + [out] IMFStreamSink **stream_sink); + HRESULT RemoveStreamSink([in] DWORD stream_sink_id); + HRESULT GetStreamSinkCount([out] DWORD *count); + HRESULT GetStreamSinkByIndex([in] DWORD index, [out] IMFStreamSink **sink); + HRESULT GetStreamSinkById([in] DWORD stream_sink_id, [out] IMFStreamSink **sink); + HRESULT SetPresentationClock([in] IMFPresentationClock *clock); + HRESULT GetPresentationClock([out] IMFPresentationClock **clock); + HRESULT Shutdown(); +} + cpp_quote("#define MF_RESOLUTION_MEDIASOURCE 0x00000001") cpp_quote("#define MF_RESOLUTION_BYTESTREAM 0x00000002") cpp_quote("#define MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE 0x00000010") diff --git a/include/mfreadwrite.idl b/include/mfreadwrite.idl index 8547b80e02c..82f67d499cc 100644 --- a/include/mfreadwrite.idl +++ b/include/mfreadwrite.idl @@ -145,6 +145,8 @@ interface IMFReadWriteClassFactory : IUnknown [in] REFIID riid, [out, iid_is(riid)] void **object ); } +cpp_quote( "HRESULT WINAPI MFCreateSinkWriterFromMediaSink(IMFMediaSink *sink, IMFAttributes *attributes," ) +cpp_quote( " IMFSinkWriter **writer);" ) cpp_quote( "HRESULT WINAPI MFCreateSourceReaderFromByteStream(IMFByteStream *stream, IMFAttributes *attributes," ) cpp_quote( " IMFSourceReader **reader);" ) cpp_quote( "HRESULT WINAPI MFCreateSourceReaderFromMediaSource(IMFMediaSource *source, IMFAttributes *attributes," )