From: Ziqing Hui zhui@codeweavers.com
--- dlls/mfreadwrite/tests/mfplat.c | 3 -- dlls/mfreadwrite/writer.c | 75 +++++++++++++++++++++++++++++---- 2 files changed, 67 insertions(+), 11 deletions(-)
diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c index bc6d8a2ca8f..81bfc3eda76 100644 --- a/dlls/mfreadwrite/tests/mfplat.c +++ b/dlls/mfreadwrite/tests/mfplat.c @@ -1840,15 +1840,12 @@ static void test_sink_writer_add_stream(void) init_media_type(input_type, video_input_type_desc, -1);
hr = IMFSinkWriter_SetInputMediaType(writer, 0xdeadbeef, NULL, NULL); - todo_wine ok(hr == E_INVALIDARG, "SetInputMediaType returned %#lx.\n", hr);
hr = IMFSinkWriter_SetInputMediaType(writer, 0, NULL, NULL); - todo_wine ok(hr == E_INVALIDARG, "SetInputMediaType returned %#lx.\n", hr);
hr = IMFSinkWriter_SetInputMediaType(writer, 0xdeadbeef, input_type, NULL); - todo_wine ok(hr == MF_E_INVALIDSTREAMNUMBER, "SetInputMediaType returned %#lx.\n", hr);
hr = IMFSinkWriter_SetInputMediaType(writer, 0, input_type, NULL); diff --git a/dlls/mfreadwrite/writer.c b/dlls/mfreadwrite/writer.c index a845058ed32..d420f5971fb 100644 --- a/dlls/mfreadwrite/writer.c +++ b/dlls/mfreadwrite/writer.c @@ -181,6 +181,32 @@ static void stream_release_transforms(struct stream *stream) memset(stream->transforms, 0, sizeof(stream->transforms)); }
+static HRESULT stream_get_type(struct stream *stream, IMFMediaType **out_type) +{ + IMFMediaTypeHandler *type_handler; + HRESULT hr; + + if (FAILED(hr = IMFStreamSink_GetMediaTypeHandler(stream->stream_sink, &type_handler))) + return hr; + hr = IMFMediaTypeHandler_GetCurrentMediaType(type_handler, out_type); + + IMFMediaTypeHandler_Release(type_handler); + return hr; +} + +static HRESULT stream_create_transforms(struct stream *stream, + IMFMediaType *input_type, IMFMediaType *output_type, BOOL use_encoder) +{ + return E_NOTIMPL; +} + +static struct stream *sink_writer_get_stream(const struct sink_writer *writer, DWORD index) +{ + if (index >= writer->streams.count) + return NULL; + return &writer->streams.items[index]; +} + static void sink_writer_release_pending_item(struct pending_item *item) { list_remove(&item->entry); @@ -324,9 +350,48 @@ static HRESULT WINAPI sink_writer_AddStream(IMFSinkWriterEx *iface, IMFMediaType static HRESULT WINAPI sink_writer_SetInputMediaType(IMFSinkWriterEx *iface, DWORD index, IMFMediaType *type, IMFAttributes *parameters) { - FIXME("%p, %lu, %p, %p.\n", iface, index, type, parameters); + struct sink_writer *writer = impl_from_IMFSinkWriterEx(iface); + IMFMediaType *stream_type = NULL; + struct stream *stream; + DWORD flags; + HRESULT hr;
- return E_NOTIMPL; + TRACE("%p, %lu, %p, %p.\n", iface, index, type, parameters); + + if (!type) + return E_INVALIDARG; + + EnterCriticalSection(&writer->cs); + + if (!(stream = sink_writer_get_stream(writer, index))) + { + hr = MF_E_INVALIDSTREAMNUMBER; + goto done; + } + + if (FAILED(hr = stream_get_type(stream, &stream_type)) + || FAILED(hr = IMFMediaType_IsEqual(type, stream_type, &flags))) + goto done; + + if (!(flags & MF_MEDIATYPE_EQUAL_MAJOR_TYPES)) + { + hr = MF_E_INVALIDMEDIATYPE; + goto done; + } + + /* Types are not compatible, create transforms. */ + if (!(flags & MF_MEDIATYPE_EQUAL_FORMAT_DATA)) + { + /* Try only using converter first, then try again with encoder. */ + if (FAILED(hr = stream_create_transforms(stream, type, stream_type, FALSE))) + hr = stream_create_transforms(stream, type, stream_type, TRUE); + } + +done: + if (stream_type) + IMFMediaType_Release(stream_type); + LeaveCriticalSection(&writer->cs); + return hr; }
static HRESULT sink_writer_set_presentation_clock(struct sink_writer *writer) @@ -391,12 +456,6 @@ static HRESULT WINAPI sink_writer_BeginWriting(IMFSinkWriterEx *iface) return hr; }
-static struct stream * sink_writer_get_stream(const struct sink_writer *writer, DWORD index) -{ - if (index >= writer->streams.count) return NULL; - return &writer->streams.items[index]; -} - static HRESULT sink_writer_get_buffer_length(IMFSample *sample, LONGLONG *timestamp, DWORD *length) { IMFMediaBuffer *buffer;