From: Ziqing Hui zhui@codeweavers.com
We'll implement create_transform later. --- dlls/mfreadwrite/tests/mfplat.c | 3 -- dlls/mfreadwrite/writer.c | 61 ++++++++++++++++++++++++++++----- 2 files changed, 53 insertions(+), 11 deletions(-)
diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c index ad5506e8dd5..fcc3ce70702 100644 --- a/dlls/mfreadwrite/tests/mfplat.c +++ b/dlls/mfreadwrite/tests/mfplat.c @@ -1730,13 +1730,10 @@ static void test_sink_writer_mp4(void) /* Test SetInputMediaType. */ 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); todo_wine diff --git a/dlls/mfreadwrite/writer.c b/dlls/mfreadwrite/writer.c index 5a03766b347..e0031c3ec28 100644 --- a/dlls/mfreadwrite/writer.c +++ b/dlls/mfreadwrite/writer.c @@ -181,6 +181,19 @@ static void stream_release_transforms(struct stream *stream) memset(stream->transforms, 0, sizeof(stream->transforms)); }
+static HRESULT create_transform(IMFMediaType *input_type, IMFMediaType *output_type, BOOL use_encoder, + struct transform *out) +{ + 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); @@ -321,8 +334,46 @@ static HRESULT WINAPI sink_writer_AddStream(IMFSinkWriter *iface, IMFMediaType * static HRESULT WINAPI sink_writer_SetInputMediaType(IMFSinkWriter *iface, DWORD index, IMFMediaType *type, IMFAttributes *parameters) { - FIXME("%p, %lu, %p, %p.\n", iface, index, type, parameters); - return E_NOTIMPL; + struct sink_writer *writer = impl_from_IMFSinkWriter(iface); + IMFMediaTypeHandler *type_handler = NULL; + struct transform transforms[2] = {}; + IMFMediaType *stream_type = NULL; + struct stream *stream; + HRESULT hr; + + 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))) + { + LeaveCriticalSection(&writer->cs); + return MF_E_INVALIDSTREAMNUMBER; + } + + /* Get stream type from stream sink. */ + if (SUCCEEDED(hr = IMFStreamSink_GetMediaTypeHandler(stream->stream_sink, &type_handler)) + && SUCCEEDED((hr = IMFMediaTypeHandler_GetCurrentMediaType(type_handler, &stream_type)))) + { + /* Create transforms for encoding. + * Try converter first, then try again with encoder. */ + if (SUCCEEDED(hr = create_transform(type, stream_type, FALSE, transforms)) + || SUCCEEDED(hr = create_transform(type, stream_type, TRUE, transforms))) + { + stream_release_transforms(stream); + stream->transforms[0] = transforms[0]; + stream->transforms[1] = transforms[1]; + } + + IMFMediaType_Release(stream_type); + IMFMediaTypeHandler_Release(type_handler); + } + + LeaveCriticalSection(&writer->cs); + return hr; }
static HRESULT sink_writer_set_presentation_clock(struct sink_writer *writer) @@ -387,12 +438,6 @@ static HRESULT WINAPI sink_writer_BeginWriting(IMFSinkWriter *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;