From: Ziqing Hui zhui@codeweavers.com
--- dlls/mfreadwrite/tests/mfplat.c | 34 ++++------ dlls/mfreadwrite/writer.c | 116 +++++++++++++++++++++----------- 2 files changed, 90 insertions(+), 60 deletions(-)
diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c index 3174a08e3d4..e97b30705a3 100644 --- a/dlls/mfreadwrite/tests/mfplat.c +++ b/dlls/mfreadwrite/tests/mfplat.c @@ -1690,7 +1690,6 @@ static void test_sink_writer_mp4(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);
/* BeginWriting fails before calling AddStream. */ @@ -1721,11 +1720,8 @@ static void test_sink_writer_mp4(void) ok(hr == MF_E_UNSUPPORTED_SERVICE, "GetServiceForStream returned %#lx.\n", hr); ok(!transform, "Unexpected pointer %p.\n", transform);
- if (writer_ex) - { - hr = IMFSinkWriterEx_GetTransformForStream(writer_ex, 0, 0, &guid, &transform); - ok(hr == MF_E_INVALIDINDEX, "GetTransformForStream returned %#lx.\n", hr); - } + hr = IMFSinkWriterEx_GetTransformForStream(writer_ex, 0, 0, &guid, &transform); + ok(hr == MF_E_INVALIDINDEX, "GetTransformForStream returned %#lx.\n", hr);
/* Test SetInputMediaType. */ init_media_type(input_type, video_input_type_desc, -1); @@ -1741,24 +1737,20 @@ static void test_sink_writer_mp4(void) /* Get transform after SetInputMediaType. */ hr = IMFSinkWriter_GetServiceForStream(writer, 0, &GUID_NULL, &IID_IMFTransform, (void **)&transform); ok(hr == S_OK, "GetServiceForStream returned %#lx.\n", hr); - if (hr == S_OK) - IMFTransform_Release(transform); + IMFTransform_Release(transform);
- if (writer_ex) - { - hr = IMFSinkWriterEx_GetTransformForStream(writer_ex, 0, 0, &guid, &transform); - ok(hr == S_OK, "GetTransformForStream returned %#lx.\n", hr); - ok(IsEqualGUID(&guid, &MFT_CATEGORY_VIDEO_PROCESSOR), "Unexpected guid %s.\n", debugstr_guid(&guid)); - IMFTransform_Release(transform); + hr = IMFSinkWriterEx_GetTransformForStream(writer_ex, 0, 0, &guid, &transform); + ok(hr == S_OK, "GetTransformForStream returned %#lx.\n", hr); + ok(IsEqualGUID(&guid, &MFT_CATEGORY_VIDEO_PROCESSOR), "Unexpected guid %s.\n", debugstr_guid(&guid)); + IMFTransform_Release(transform);
- hr = IMFSinkWriterEx_GetTransformForStream(writer_ex, 0, 1, &guid, &transform); - ok(hr == S_OK, "GetTransformForStream returned %#lx.\n", hr); - ok(IsEqualGUID(&guid, &MFT_CATEGORY_VIDEO_ENCODER), "Unexpected guid %s.\n", debugstr_guid(&guid)); - IMFTransform_Release(transform); + hr = IMFSinkWriterEx_GetTransformForStream(writer_ex, 0, 1, &guid, &transform); + ok(hr == S_OK, "GetTransformForStream returned %#lx.\n", hr); + ok(IsEqualGUID(&guid, &MFT_CATEGORY_VIDEO_ENCODER), "Unexpected guid %s.\n", debugstr_guid(&guid)); + IMFTransform_Release(transform);
- hr = IMFSinkWriterEx_GetTransformForStream(writer_ex, 0, 2, &guid, &transform); - ok(hr == MF_E_INVALIDINDEX, "GetTransformForStream returned %#lx.\n", hr); - } + hr = IMFSinkWriterEx_GetTransformForStream(writer_ex, 0, 2, &guid, &transform); + ok(hr == MF_E_INVALIDINDEX, "GetTransformForStream returned %#lx.\n", hr);
/* Get media sink before BeginWriting. */ sink = (void *)0xdeadbeef; diff --git a/dlls/mfreadwrite/writer.c b/dlls/mfreadwrite/writer.c index 2ec7d5d99e3..c05fe4a9cbc 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;
@@ -94,9 +94,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) @@ -324,15 +324,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; }
@@ -341,9 +342,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); @@ -361,9 +362,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;
@@ -421,9 +422,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; @@ -453,10 +454,10 @@ 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) { - struct sink_writer *writer = impl_from_IMFSinkWriter(iface); + struct sink_writer *writer = impl_from_IMFSinkWriterEx(iface); IMFMediaTypeHandler *type_handler = NULL; struct transform transforms[2] = {}; IMFMediaType *stream_type = NULL; @@ -517,9 +518,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;
@@ -737,9 +738,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; @@ -776,9 +777,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)); @@ -795,9 +796,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;
@@ -819,9 +820,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;
@@ -850,9 +851,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;
@@ -881,7 +882,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);
@@ -907,10 +908,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;
@@ -938,9 +939,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;
@@ -968,7 +969,43 @@ 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; + + EnterCriticalSection(&writer->cs); + + if (!(stream = sink_writer_get_stream(writer, stream_index))) + { + LeaveCriticalSection(&writer->cs); + return MF_E_INVALIDSTREAMNUMBER; + } + + if (transform_index > 1 || !stream->transforms[transform_index].transform) + { + LeaveCriticalSection(&writer->cs); + return MF_E_INVALIDINDEX; + } + + entry = &stream->transforms[transform_index]; + 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, @@ -984,6 +1021,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, @@ -1005,13 +1043,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, @@ -1155,7 +1193,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; @@ -1171,12 +1209,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; }