From: Ziqing Hui zhui@codeweavers.com
We'll implement create_transform_entry later. --- dlls/mfreadwrite/writer.c | 61 ++++++++++++++++++++++++++++++++++----- 1 file changed, 53 insertions(+), 8 deletions(-)
diff --git a/dlls/mfreadwrite/writer.c b/dlls/mfreadwrite/writer.c index b4d71dfd942..48ff27f14d1 100644 --- a/dlls/mfreadwrite/writer.c +++ b/dlls/mfreadwrite/writer.c @@ -172,6 +172,12 @@ static HRESULT create_marker_context(unsigned int marker_type, void *user_contex return S_OK; }
+static HRESULT create_transform_entry(IMFMediaType *input_type, IMFMediaType *output_type, BOOL use_encoder, + struct transform_entry **out) +{ + return E_NOTIMPL; +} + static void stream_release_transforms(struct stream *stream) { struct transform_entry *entry, *next; @@ -185,6 +191,13 @@ static void stream_release_transforms(struct stream *stream) } }
+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); @@ -326,8 +339,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_entry *entry = NULL; + 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_entry(type, stream_type, FALSE, &entry)) + || SUCCEEDED(hr = create_transform_entry(type, stream_type, TRUE, &entry))) + { + if (!list_empty(&stream->transforms)) + stream_release_transforms(stream); + list_add_tail(&stream->transforms, &entry->entry); + } + + IMFMediaType_Release(stream_type); + IMFMediaTypeHandler_Release(type_handler); + } + + LeaveCriticalSection(&writer->cs); + return hr; }
static HRESULT sink_writer_set_presentation_clock(struct sink_writer *writer) @@ -391,12 +442,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;