Signed-off-by: Nikolay Sivov nsivov@codeweavers.com ---
A fix from ec5bd49bf85606a7a4b1a5f4146fbaabf53c1256 applied to the Reader API.
dlls/mfreadwrite/reader.c | 44 ++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 15 deletions(-)
diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c index ab959c26165..cb4166265a0 100644 --- a/dlls/mfreadwrite/reader.c +++ b/dlls/mfreadwrite/reader.c @@ -105,11 +105,17 @@ enum media_stream_flags STREAM_FLAG_PRESENTED = 0x4, /* Set if stream was selected last time Start() was called. */ };
+struct stream_transform +{ + IMFTransform *transform; + unsigned int min_buffer_size; +}; + struct media_stream { IMFMediaStream *stream; IMFMediaType *current; - IMFTransform *decoder; + struct stream_transform decoder; IMFVideoSampleAllocatorEx *allocator; IMFVideoSampleAllocatorNotify notify_cb; unsigned int id; @@ -643,12 +649,13 @@ static HRESULT source_reader_pull_stream_samples(struct source_reader *reader, s { MFT_OUTPUT_STREAM_INFO stream_info = { 0 }; MFT_OUTPUT_DATA_BUFFER out_buffer; + unsigned int buffer_size; IMFMediaBuffer *buffer; LONGLONG timestamp; DWORD status; HRESULT hr;
- if (FAILED(hr = IMFTransform_GetOutputStreamInfo(stream->decoder, 0, &stream_info))) + if (FAILED(hr = IMFTransform_GetOutputStreamInfo(stream->decoder.transform, 0, &stream_info))) { WARN("Failed to get output stream info, hr %#x.\n", hr); return hr; @@ -663,7 +670,9 @@ static HRESULT source_reader_pull_stream_samples(struct source_reader *reader, s if (FAILED(hr = MFCreateSample(&out_buffer.pSample))) break;
- if (FAILED(hr = MFCreateAlignedMemoryBuffer(stream_info.cbSize, stream_info.cbAlignment, &buffer))) + buffer_size = max(stream_info.cbSize, stream->decoder.min_buffer_size); + + if (FAILED(hr = MFCreateAlignedMemoryBuffer(buffer_size, stream_info.cbAlignment, &buffer))) { IMFSample_Release(out_buffer.pSample); break; @@ -673,7 +682,7 @@ static HRESULT source_reader_pull_stream_samples(struct source_reader *reader, s IMFMediaBuffer_Release(buffer); }
- if (FAILED(hr = IMFTransform_ProcessOutput(stream->decoder, 0, 1, &out_buffer, &status))) + if (FAILED(hr = IMFTransform_ProcessOutput(stream->decoder.transform, 0, 1, &out_buffer, &status))) { if (out_buffer.pSample) IMFSample_Release(out_buffer.pSample); @@ -700,7 +709,7 @@ static HRESULT source_reader_process_sample(struct source_reader *reader, struct LONGLONG timestamp; HRESULT hr;
- if (!stream->decoder) + if (!stream->decoder.transform) { timestamp = 0; if (FAILED(IMFSample_GetSampleTime(sample, ×tamp))) @@ -715,7 +724,7 @@ static HRESULT source_reader_process_sample(struct source_reader *reader, struct hr = source_reader_pull_stream_samples(reader, stream); if (hr == MF_E_TRANSFORM_NEED_MORE_INPUT) { - if (FAILED(hr = IMFTransform_ProcessInput(stream->decoder, 0, sample, 0))) + if (FAILED(hr = IMFTransform_ProcessInput(stream->decoder.transform, 0, sample, 0))) { WARN("Transform failed to process input, hr %#x.\n", hr); return hr; @@ -812,7 +821,7 @@ static HRESULT source_reader_media_stream_state_handler(struct source_reader *re stream->state = STREAM_STATE_EOS; stream->flags &= ~STREAM_FLAG_SAMPLE_REQUESTED;
- if (stream->decoder && SUCCEEDED(IMFTransform_ProcessMessage(stream->decoder, + if (stream->decoder.transform && SUCCEEDED(IMFTransform_ProcessMessage(stream->decoder.transform, MFT_MESSAGE_COMMAND_DRAIN, 0))) { if ((hr = source_reader_pull_stream_samples(reader, stream)) != MF_E_TRANSFORM_NEED_MORE_INPUT) @@ -1161,8 +1170,8 @@ static void source_reader_flush_stream(struct source_reader *reader, DWORD strea struct media_stream *stream = &reader->streams[stream_index];
source_reader_release_responses(reader, stream); - if (stream->decoder) - IMFTransform_ProcessMessage(stream->decoder, MFT_MESSAGE_COMMAND_FLUSH, 0); + if (stream->decoder.transform) + IMFTransform_ProcessMessage(stream->decoder.transform, MFT_MESSAGE_COMMAND_FLUSH, 0); stream->requests = 0; }
@@ -1378,8 +1387,8 @@ static ULONG WINAPI src_reader_Release(IMFSourceReader *iface) IMFMediaStream_Release(stream->stream); if (stream->current) IMFMediaType_Release(stream->current); - if (stream->decoder) - IMFTransform_Release(stream->decoder); + if (stream->decoder.transform) + IMFTransform_Release(stream->decoder.transform); if (stream->allocator) IMFVideoSampleAllocatorEx_Release(stream->allocator); } @@ -1672,8 +1681,10 @@ static HRESULT source_reader_configure_decoder(struct source_reader *reader, DWO IMFMediaType *input_type, IMFMediaType *output_type) { IMFMediaTypeHandler *type_handler; + unsigned int block_alignment = 0; IMFTransform *transform = NULL; IMFMediaType *type = NULL; + GUID major = { 0 }; DWORD flags; HRESULT hr; int i = 0; @@ -1710,12 +1721,15 @@ static HRESULT source_reader_configure_decoder(struct source_reader *reader, DWO
if (FAILED(hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *)reader->streams[index].current))) WARN("Failed to copy attributes, hr %#x.\n", hr); + if (SUCCEEDED(IMFMediaType_GetMajorType(type, &major)) && IsEqualGUID(&major, &MFMediaType_Audio)) + IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &block_alignment); IMFMediaType_Release(type);
- if (reader->streams[index].decoder) - IMFTransform_Release(reader->streams[index].decoder); + if (reader->streams[index].decoder.transform) + IMFTransform_Release(reader->streams[index].decoder.transform);
- reader->streams[index].decoder = transform; + reader->streams[index].decoder.transform = transform; + reader->streams[index].decoder.min_buffer_size = block_alignment;
return S_OK; } @@ -2082,7 +2096,7 @@ static HRESULT WINAPI src_reader_GetServiceForStream(IMFSourceReader *iface, DWO hr = MF_E_INVALIDSTREAMNUMBER; else { - obj = (IUnknown *)reader->streams[index].decoder; + obj = (IUnknown *)reader->streams[index].decoder.transform; if (!obj) hr = E_NOINTERFACE; } break;