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, &timestamp)))
@@ -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