From: Ziqing Hui zhui@codeweavers.com
--- dlls/mfreadwrite/tests/mfplat.c | 13 ++-- dlls/mfreadwrite/writer.c | 126 ++++++++++++++++++++++---------- 2 files changed, 94 insertions(+), 45 deletions(-)
diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c index 7ed757073ff..bc6d8a2ca8f 100644 --- a/dlls/mfreadwrite/tests/mfplat.c +++ b/dlls/mfreadwrite/tests/mfplat.c @@ -1698,7 +1698,6 @@ static void test_sink_writer_get_object(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = IMFSinkWriter_QueryInterface(writer, &IID_IMFSinkWriterEx, (void **)&writer_ex); - todo_wine ok(hr == S_OK, "QueryInterface returned %#lx.\n", hr);
hr = MFCreateMediaType(&stream_type); @@ -1715,13 +1714,10 @@ static void test_sink_writer_get_object(void) ok(hr == MF_E_UNSUPPORTED_SERVICE, "GetServiceForStream returned %#lx.\n", hr); ok(!transform, "Unexpected transform %p.\n", transform);
- if (writer_ex) - { transform = (void *)0xdeadbeef; hr = IMFSinkWriterEx_GetTransformForStream(writer_ex, 0, 0, &guid, &transform); ok(hr == MF_E_INVALIDINDEX, "GetTransformForStream returned %#lx.\n", hr); ok(!transform, "Unexpected transform %p.\n", transform); - }
hr = MFCreateMediaType(&input_type); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -1738,23 +1734,26 @@ static void test_sink_writer_get_object(void) if (hr == S_OK) IMFTransform_Release(transform);
- if (writer_ex) - { hr = IMFSinkWriterEx_GetTransformForStream(writer_ex, 0, 0, &guid, &transform); + todo_wine ok(hr == S_OK, "GetTransformForStream returned %#lx.\n", hr); + todo_wine ok(IsEqualGUID(&guid, &MFT_CATEGORY_VIDEO_PROCESSOR), "Unexpected guid %s.\n", debugstr_guid(&guid)); + if (hr == S_OK) IMFTransform_Release(transform);
hr = IMFSinkWriterEx_GetTransformForStream(writer_ex, 0, 1, &guid, &transform); + todo_wine ok(hr == S_OK, "GetTransformForStream returned %#lx.\n", hr); + todo_wine ok(IsEqualGUID(&guid, &MFT_CATEGORY_VIDEO_ENCODER), "Unexpected guid %s.\n", debugstr_guid(&guid)); + if (hr == S_OK) IMFTransform_Release(transform);
transform = (void *)0xdeadbeef; hr = IMFSinkWriterEx_GetTransformForStream(writer_ex, 0, 2, &guid, &transform); ok(hr == MF_E_INVALIDINDEX, "GetTransformForStream returned %#lx.\n", hr); ok(!transform, "Unexpected transform %p.\n", transform); - }
/* Get media sink before BeginWriting. */ sink = (void *)0xdeadbeef; diff --git a/dlls/mfreadwrite/writer.c b/dlls/mfreadwrite/writer.c index fc99bb4cc4e..8ae56b171f1 100644 --- a/dlls/mfreadwrite/writer.c +++ b/dlls/mfreadwrite/writer.c @@ -71,7 +71,7 @@ struct stream
struct sink_writer { - IMFSinkWriter IMFSinkWriter_iface; + IMFSinkWriterEx IMFSinkWriterEx_iface; IMFAsyncCallback events_callback; LONG refcount;
@@ -95,9 +95,9 @@ struct sink_writer CRITICAL_SECTION cs; };
-static struct sink_writer *impl_from_IMFSinkWriter(IMFSinkWriter *iface) +static struct sink_writer *impl_from_IMFSinkWriterEx(IMFSinkWriterEx *iface) { - return CONTAINING_RECORD(iface, struct sink_writer, IMFSinkWriter_iface); + return CONTAINING_RECORD(iface, struct sink_writer, IMFSinkWriterEx_iface); }
static struct sink_writer *impl_from_events_callback_IMFAsyncCallback(IMFAsyncCallback *iface) @@ -191,15 +191,16 @@ static void sink_writer_release_pending_item(struct pending_item *item) free(item); }
-static HRESULT WINAPI sink_writer_QueryInterface(IMFSinkWriter *iface, REFIID riid, void **out) +static HRESULT WINAPI sink_writer_QueryInterface(IMFSinkWriterEx *iface, REFIID riid, void **out) { TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out);
- if (IsEqualIID(riid, &IID_IMFSinkWriter) || - IsEqualIID(riid, &IID_IUnknown)) + if (IsEqualIID(riid, &IID_IMFSinkWriterEx) + || IsEqualIID(riid, &IID_IMFSinkWriter) + || IsEqualIID(riid, &IID_IUnknown)) { *out = iface; - IMFSinkWriter_AddRef(iface); + IMFSinkWriterEx_AddRef(iface); return S_OK; }
@@ -208,9 +209,9 @@ static HRESULT WINAPI sink_writer_QueryInterface(IMFSinkWriter *iface, REFIID ri return E_NOINTERFACE; }
-static ULONG WINAPI sink_writer_AddRef(IMFSinkWriter *iface) +static ULONG WINAPI sink_writer_AddRef(IMFSinkWriterEx *iface) { - struct sink_writer *writer = impl_from_IMFSinkWriter(iface); + struct sink_writer *writer = impl_from_IMFSinkWriterEx(iface); ULONG refcount = InterlockedIncrement(&writer->refcount);
TRACE("%p, %lu.\n", iface, refcount); @@ -228,9 +229,9 @@ static void sink_writer_drop_pending_items(struct stream *stream) } }
-static ULONG WINAPI sink_writer_Release(IMFSinkWriter *iface) +static ULONG WINAPI sink_writer_Release(IMFSinkWriterEx *iface) { - struct sink_writer *writer = impl_from_IMFSinkWriter(iface); + struct sink_writer *writer = impl_from_IMFSinkWriterEx(iface); ULONG refcount = InterlockedDecrement(&writer->refcount); unsigned int i;
@@ -290,9 +291,9 @@ static HRESULT sink_writer_add_stream(struct sink_writer *writer, IMFStreamSink return hr; }
-static HRESULT WINAPI sink_writer_AddStream(IMFSinkWriter *iface, IMFMediaType *media_type, DWORD *index) +static HRESULT WINAPI sink_writer_AddStream(IMFSinkWriterEx *iface, IMFMediaType *media_type, DWORD *index) { - struct sink_writer *writer = impl_from_IMFSinkWriter(iface); + struct sink_writer *writer = impl_from_IMFSinkWriterEx(iface); HRESULT hr = MF_E_INVALIDREQUEST; IMFStreamSink *stream_sink; DWORD id; @@ -322,7 +323,7 @@ static HRESULT WINAPI sink_writer_AddStream(IMFSinkWriter *iface, IMFMediaType * return hr; }
-static HRESULT WINAPI sink_writer_SetInputMediaType(IMFSinkWriter *iface, DWORD index, IMFMediaType *type, +static HRESULT WINAPI sink_writer_SetInputMediaType(IMFSinkWriterEx *iface, DWORD index, IMFMediaType *type, IMFAttributes *parameters) { FIXME("%p, %lu, %p, %p.\n", iface, index, type, parameters); @@ -349,9 +350,9 @@ static HRESULT sink_writer_set_presentation_clock(struct sink_writer *writer) return hr; }
-static HRESULT WINAPI sink_writer_BeginWriting(IMFSinkWriter *iface) +static HRESULT WINAPI sink_writer_BeginWriting(IMFSinkWriterEx *iface) { - struct sink_writer *writer = impl_from_IMFSinkWriter(iface); + struct sink_writer *writer = impl_from_IMFSinkWriterEx(iface); HRESULT hr = S_OK; unsigned int i;
@@ -575,9 +576,9 @@ static HRESULT sink_writer_write_sample(struct sink_writer *writer, struct strea return hr; }
-static HRESULT WINAPI sink_writer_WriteSample(IMFSinkWriter *iface, DWORD index, IMFSample *sample) +static HRESULT WINAPI sink_writer_WriteSample(IMFSinkWriterEx *iface, DWORD index, IMFSample *sample) { - struct sink_writer *writer = impl_from_IMFSinkWriter(iface); + struct sink_writer *writer = impl_from_IMFSinkWriterEx(iface); struct stream *stream; LONGLONG timestamp; DWORD length; @@ -614,9 +615,9 @@ static HRESULT WINAPI sink_writer_WriteSample(IMFSinkWriter *iface, DWORD index, return hr; }
-static HRESULT WINAPI sink_writer_SendStreamTick(IMFSinkWriter *iface, DWORD index, LONGLONG timestamp) +static HRESULT WINAPI sink_writer_SendStreamTick(IMFSinkWriterEx *iface, DWORD index, LONGLONG timestamp) { - struct sink_writer *writer = impl_from_IMFSinkWriter(iface); + struct sink_writer *writer = impl_from_IMFSinkWriterEx(iface); HRESULT hr;
TRACE("%p, %lu, %s.\n", iface, index, wine_dbgstr_longlong(timestamp)); @@ -633,9 +634,9 @@ static HRESULT WINAPI sink_writer_SendStreamTick(IMFSinkWriter *iface, DWORD ind return hr; }
-static HRESULT WINAPI sink_writer_PlaceMarker(IMFSinkWriter *iface, DWORD index, void *user_context) +static HRESULT WINAPI sink_writer_PlaceMarker(IMFSinkWriterEx *iface, DWORD index, void *user_context) { - struct sink_writer *writer = impl_from_IMFSinkWriter(iface); + struct sink_writer *writer = impl_from_IMFSinkWriterEx(iface); struct stream *stream; HRESULT hr;
@@ -657,9 +658,9 @@ static HRESULT WINAPI sink_writer_PlaceMarker(IMFSinkWriter *iface, DWORD index, return hr; }
-static HRESULT WINAPI sink_writer_NotifyEndOfSegment(IMFSinkWriter *iface, DWORD index) +static HRESULT WINAPI sink_writer_NotifyEndOfSegment(IMFSinkWriterEx *iface, DWORD index) { - struct sink_writer *writer = impl_from_IMFSinkWriter(iface); + struct sink_writer *writer = impl_from_IMFSinkWriterEx(iface); HRESULT hr = S_OK; unsigned int i;
@@ -688,9 +689,9 @@ static HRESULT WINAPI sink_writer_NotifyEndOfSegment(IMFSinkWriter *iface, DWORD return hr; }
-static HRESULT WINAPI sink_writer_Flush(IMFSinkWriter *iface, DWORD index) +static HRESULT WINAPI sink_writer_Flush(IMFSinkWriterEx *iface, DWORD index) { - struct sink_writer *writer = impl_from_IMFSinkWriter(iface); + struct sink_writer *writer = impl_from_IMFSinkWriterEx(iface); HRESULT hr = S_OK; unsigned int i;
@@ -719,7 +720,7 @@ static HRESULT WINAPI sink_writer_Flush(IMFSinkWriter *iface, DWORD index) return hr; }
-static HRESULT WINAPI sink_writer_Finalize(IMFSinkWriter *iface) +static HRESULT WINAPI sink_writer_Finalize(IMFSinkWriterEx *iface) { FIXME("%p.\n", iface);
@@ -745,10 +746,10 @@ static HRESULT sink_writer_get_service(void *object, REFGUID service, REFIID rii return hr; }
-static HRESULT WINAPI sink_writer_GetServiceForStream(IMFSinkWriter *iface, DWORD index, REFGUID service, +static HRESULT WINAPI sink_writer_GetServiceForStream(IMFSinkWriterEx *iface, DWORD index, REFGUID service, REFIID riid, void **object) { - struct sink_writer *writer = impl_from_IMFSinkWriter(iface); + struct sink_writer *writer = impl_from_IMFSinkWriterEx(iface); HRESULT hr = E_UNEXPECTED; struct stream *stream;
@@ -776,9 +777,9 @@ static HRESULT WINAPI sink_writer_GetServiceForStream(IMFSinkWriter *iface, DWOR return hr; }
-static HRESULT WINAPI sink_writer_GetStatistics(IMFSinkWriter *iface, DWORD index, MF_SINK_WRITER_STATISTICS *stats) +static HRESULT WINAPI sink_writer_GetStatistics(IMFSinkWriterEx *iface, DWORD index, MF_SINK_WRITER_STATISTICS *stats) { - struct sink_writer *writer = impl_from_IMFSinkWriter(iface); + struct sink_writer *writer = impl_from_IMFSinkWriterEx(iface); struct stream *stream; HRESULT hr = S_OK;
@@ -806,7 +807,55 @@ static HRESULT WINAPI sink_writer_GetStatistics(IMFSinkWriter *iface, DWORD inde return hr; }
-static const IMFSinkWriterVtbl sink_writer_vtbl = +static HRESULT WINAPI sink_writer_GetTransformForStream(IMFSinkWriterEx *iface, + DWORD stream_index, DWORD transform_index, GUID *category, IMFTransform **transform) +{ + struct sink_writer *writer = impl_from_IMFSinkWriterEx(iface); + struct transform *entry; + struct stream *stream; + + TRACE("%p, %#lx, %#lx, %p, %p.\n", iface, stream_index, transform_index, category, transform); + + if (!transform) + return E_POINTER; + *transform = NULL; + + EnterCriticalSection(&writer->cs); + + if (!(stream = sink_writer_get_stream(writer, stream_index))) + { + LeaveCriticalSection(&writer->cs); + return MF_E_INVALIDSTREAMNUMBER; + } + + switch (transform_index) + { + case 0: + entry = &stream->encoder; + break; + case 1: + entry = &stream->converter; + break; + default: + LeaveCriticalSection(&writer->cs); + return MF_E_INVALIDINDEX; + } + + if (!entry->transform) + { + LeaveCriticalSection(&writer->cs); + return MF_E_INVALIDINDEX; + } + + IMFTransform_AddRef((*transform = entry->transform)); + if (category) + *category = entry->category; + + LeaveCriticalSection(&writer->cs); + return S_OK; +} + +static const IMFSinkWriterExVtbl sink_writer_vtbl = { sink_writer_QueryInterface, sink_writer_AddRef, @@ -822,6 +871,7 @@ static const IMFSinkWriterVtbl sink_writer_vtbl = sink_writer_Finalize, sink_writer_GetServiceForStream, sink_writer_GetStatistics, + sink_writer_GetTransformForStream, };
static HRESULT WINAPI sink_writer_callback_QueryInterface(IMFAsyncCallback *iface, @@ -843,13 +893,13 @@ static HRESULT WINAPI sink_writer_callback_QueryInterface(IMFAsyncCallback *ifac static ULONG WINAPI sink_writer_events_callback_AddRef(IMFAsyncCallback *iface) { struct sink_writer *writer = impl_from_events_callback_IMFAsyncCallback(iface); - return IMFSinkWriter_AddRef(&writer->IMFSinkWriter_iface); + return IMFSinkWriterEx_AddRef(&writer->IMFSinkWriterEx_iface); }
static ULONG WINAPI sink_writer_events_callback_Release(IMFAsyncCallback *iface) { struct sink_writer *writer = impl_from_events_callback_IMFAsyncCallback(iface); - return IMFSinkWriter_Release(&writer->IMFSinkWriter_iface); + return IMFSinkWriterEx_Release(&writer->IMFSinkWriterEx_iface); }
static HRESULT WINAPI sink_writer_callback_GetParameters(IMFAsyncCallback *iface, @@ -993,7 +1043,7 @@ HRESULT create_sink_writer_from_sink(IMFMediaSink *sink, IMFAttributes *attribut if (!(object = calloc(1, sizeof(*object)))) return E_OUTOFMEMORY;
- object->IMFSinkWriter_iface.lpVtbl = &sink_writer_vtbl; + object->IMFSinkWriterEx_iface.lpVtbl = &sink_writer_vtbl; object->events_callback.lpVtbl = &sink_writer_events_callback_vtbl; object->refcount = 1; object->sink = sink; @@ -1010,12 +1060,12 @@ HRESULT create_sink_writer_from_sink(IMFMediaSink *sink, IMFAttributes *attribut
if (FAILED(hr = sink_writer_initialize_existing_streams(object, sink))) { - IMFSinkWriter_Release(&object->IMFSinkWriter_iface); + IMFSinkWriterEx_Release(&object->IMFSinkWriterEx_iface); return hr; }
- hr = IMFSinkWriter_QueryInterface(&object->IMFSinkWriter_iface, riid, out); - IMFSinkWriter_Release(&object->IMFSinkWriter_iface); + hr = IMFSinkWriterEx_QueryInterface(&object->IMFSinkWriterEx_iface, riid, out); + IMFSinkWriterEx_Release(&object->IMFSinkWriterEx_iface); return hr; }