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