Nikolay Sivov : mfreadwrite/reader: Consider audio block alignment when creating output buffers for the decoder.
Alexandre Julliard
julliard at winehq.org
Mon Mar 22 17:15:51 CDT 2021
Module: wine
Branch: master
Commit: ca143521ed2deaa141fdeb95e151bb276b3105b3
URL: https://source.winehq.org/git/wine.git/?a=commit;h=ca143521ed2deaa141fdeb95e151bb276b3105b3
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Mon Mar 22 10:33:42 2021 +0300
mfreadwrite/reader: Consider audio block alignment when creating output buffers for the decoder.
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
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;
More information about the wine-cvs
mailing list