[PATCH 0/3] MR10298: mfreadwrite: Implement sample encoding.
From: Ziqing Hui <zhui@codeweavers.com> --- dlls/mfreadwrite/writer.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/dlls/mfreadwrite/writer.c b/dlls/mfreadwrite/writer.c index b697c41cb4a..5dc85725d3d 100644 --- a/dlls/mfreadwrite/writer.c +++ b/dlls/mfreadwrite/writer.c @@ -298,14 +298,20 @@ static HRESULT stream_create_transforms(struct stream *stream, { /* Create the converter with a recursive call. */ hr = stream_create_transforms(stream, input_type, encoder_input_type, FALSE, attributes); - IMFMediaType_Release(encoder_input_type); if (SUCCEEDED(hr)) { /* Converter is already set in the recursive call, set encoder here. */ - stream->encoder = transform; - TRACE("Created encoder %p.", transform); - break; + if (SUCCEEDED(hr = stream_set_transform(stream, transform, encoder_input_type, output_type, TRUE))) + { + IMFMediaType_Release(encoder_input_type); + break; + } + else + { + stream_release_transforms(stream); + } } + IMFMediaType_Release(encoder_input_type); } IMFTransform_Release(transform); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10298
From: Ziqing Hui <zhui@codeweavers.com> --- dlls/mfreadwrite/tests/mfplat.c | 1 + dlls/mfreadwrite/writer.c | 67 ++++++++++++++++++++++++--------- 2 files changed, 51 insertions(+), 17 deletions(-) diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c index b258b10441e..40e697947f2 100644 --- a/dlls/mfreadwrite/tests/mfplat.c +++ b/dlls/mfreadwrite/tests/mfplat.c @@ -1950,6 +1950,7 @@ static void test_sink_writer_sample_process(void) hr = IMFSample_SetSampleDuration(sample, 333333); ok(hr == S_OK, "SetSampleDuration returned %#lx.\n", hr); hr = IMFSinkWriter_WriteSample(writer, 0, sample); + todo_wine ok(hr == S_OK, "WriteSample returned %#lx.\n", hr); IMFSample_Release(sample); } diff --git a/dlls/mfreadwrite/writer.c b/dlls/mfreadwrite/writer.c index 5dc85725d3d..43b315d5808 100644 --- a/dlls/mfreadwrite/writer.c +++ b/dlls/mfreadwrite/writer.c @@ -324,6 +324,54 @@ static HRESULT stream_create_transforms(struct stream *stream, return hr; } +static HRESULT stream_queue_sample(struct stream *stream, IMFSample *sample) +{ + struct pending_item *item; + + if (!(item = calloc(1, sizeof(*item)))) + return E_OUTOFMEMORY; + + item->sample = sample; + IMFSample_AddRef(item->sample); + list_add_tail(&stream->queue, &item->entry); + + return S_OK; +} + +static HRESULT stream_drain_transform_output(struct stream *stream, + IMFTransform *transform, IMFTransform *next_transform) +{ + /* TODO: Drain the output of the transforms. */ + return E_NOTIMPL; +} + +static HRESULT stream_encode_sample(struct stream *stream, + IMFSample *sample, IMFTransform *transform, IMFTransform *next_transform) +{ + HRESULT hr; + + if (!transform) + { + if (!next_transform) + return stream_queue_sample(stream, sample); + + transform = next_transform; + next_transform = NULL; + } + + hr = IMFTransform_ProcessInput(transform, 0, sample, 0); + if (hr == MF_E_NOTACCEPTING) + { + if (FAILED(hr = stream_drain_transform_output(stream, transform, next_transform))) + return hr; + hr = IMFTransform_ProcessInput(transform, 0, sample, 0); + } + if (FAILED(hr)) + return hr; + + return stream_drain_transform_output(stream, transform, next_transform); +} + static struct stream *sink_writer_get_stream(const struct sink_writer *writer, DWORD index) { if (index >= writer->streams.count) @@ -718,22 +766,6 @@ static HRESULT sink_writer_process_sample(struct sink_writer *writer, struct str return hr; } -static HRESULT sink_writer_encode_sample(struct sink_writer *writer, struct stream *stream, IMFSample *sample) -{ - struct pending_item *item; - - /* FIXME: call the encoder, queue its output */ - - if (!(item = calloc(1, sizeof(*item)))) - return E_OUTOFMEMORY; - - item->sample = sample; - IMFSample_AddRef(item->sample); - list_add_tail(&stream->queue, &item->entry); - - return S_OK; -} - static HRESULT sink_writer_write_sample(struct sink_writer *writer, struct stream *stream, IMFSample *sample) { LONGLONG timestamp; @@ -750,7 +782,8 @@ static HRESULT sink_writer_write_sample(struct sink_writer *writer, struct strea writer->stats.qwNumSamplesReceived++; writer->stats.dwByteCountQueued += length; - if (FAILED(hr = sink_writer_encode_sample(writer, stream, sample))) return hr; + if (FAILED(hr = stream_encode_sample(stream, sample, stream->converter, stream->encoder))) + return hr; if (stream->stats.dwNumOutstandingSinkSampleRequests) hr = sink_writer_process_sample(writer, stream); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10298
From: Ziqing Hui <zhui@codeweavers.com> --- dlls/mfreadwrite/tests/mfplat.c | 1 - dlls/mfreadwrite/writer.c | 72 ++++++++++++++++++++++++++++++++- 2 files changed, 70 insertions(+), 3 deletions(-) diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c index 40e697947f2..b258b10441e 100644 --- a/dlls/mfreadwrite/tests/mfplat.c +++ b/dlls/mfreadwrite/tests/mfplat.c @@ -1950,7 +1950,6 @@ static void test_sink_writer_sample_process(void) hr = IMFSample_SetSampleDuration(sample, 333333); ok(hr == S_OK, "SetSampleDuration returned %#lx.\n", hr); hr = IMFSinkWriter_WriteSample(writer, 0, sample); - todo_wine ok(hr == S_OK, "WriteSample returned %#lx.\n", hr); IMFSample_Release(sample); } diff --git a/dlls/mfreadwrite/writer.c b/dlls/mfreadwrite/writer.c index 43b315d5808..ff7cb6eaa77 100644 --- a/dlls/mfreadwrite/writer.c +++ b/dlls/mfreadwrite/writer.c @@ -338,11 +338,79 @@ static HRESULT stream_queue_sample(struct stream *stream, IMFSample *sample) return S_OK; } +static HRESULT allocate_transform_output(IMFTransform *transform, IMFSample **sample) +{ + MFT_OUTPUT_STREAM_INFO output_info; + IMFMediaBuffer *buffer; + HRESULT hr; + + *sample = NULL; + + if (FAILED(hr = IMFTransform_GetOutputStreamInfo(transform, 0, &output_info))) + return hr; + if (output_info.dwFlags & MFT_OUTPUT_STREAM_PROVIDES_SAMPLES) + return S_OK; + if (!output_info.cbSize) + { + if (output_info.dwFlags & MFT_OUTPUT_STREAM_CAN_PROVIDE_SAMPLES) + return S_OK; + WARN("Transform %p returned zero output cbSize.\n", transform); + return E_FAIL; + } + + if (FAILED(hr = MFCreateSample(sample))) + return hr; + if (FAILED(hr = MFCreateMemoryBuffer(output_info.cbSize, &buffer))) + { + IMFSample_Release(*sample); + *sample = NULL; + return hr; + } + hr = IMFSample_AddBuffer(*sample, buffer); + IMFMediaBuffer_Release(buffer); + if (FAILED(hr)) + { + IMFSample_Release(*sample); + *sample = NULL; + } + + return hr; +} + +static HRESULT stream_encode_sample(struct stream *stream, + IMFSample *sample, IMFTransform *transform, IMFTransform *next_transform); + static HRESULT stream_drain_transform_output(struct stream *stream, IMFTransform *transform, IMFTransform *next_transform) { - /* TODO: Drain the output of the transforms. */ - return E_NOTIMPL; + MFT_OUTPUT_DATA_BUFFER output_buffer; + HRESULT hr = S_OK; + DWORD status; + + while (SUCCEEDED(hr)) + { + memset(&output_buffer, 0, sizeof(output_buffer)); + if (FAILED(hr = allocate_transform_output(transform, &output_buffer.pSample))) + break; + + if (SUCCEEDED(hr = IMFTransform_ProcessOutput(transform, 0, 1, &output_buffer, &status))) + { + if (next_transform) + hr = stream_encode_sample(stream, output_buffer.pSample, next_transform, NULL); + else + hr = stream_queue_sample(stream, output_buffer.pSample); + } + + if (output_buffer.pSample) + IMFSample_Release(output_buffer.pSample); + if (output_buffer.pEvents) + IMFCollection_Release(output_buffer.pEvents); + } + + if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) + hr = S_OK; + + return hr; } static HRESULT stream_encode_sample(struct stream *stream, -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10298
participants (2)
-
Ziqing Hui -
Ziqing Hui (@zhui)