Nikolay Sivov : mf/session: Consider audio block alignment when creating output buffers for transforms.

Alexandre Julliard julliard at winehq.org
Fri Mar 19 16:42:01 CDT 2021


Module: wine
Branch: master
Commit: ec5bd49bf85606a7a4b1a5f4146fbaabf53c1256
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=ec5bd49bf85606a7a4b1a5f4146fbaabf53c1256

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Fri Mar 19 12:28:13 2021 +0300

mf/session: Consider audio block alignment when creating output buffers for transforms.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/mf/session.c | 44 +++++++++++++++++++++++++++++++-------------
 1 file changed, 31 insertions(+), 13 deletions(-)

diff --git a/dlls/mf/session.c b/dlls/mf/session.c
index 942212d5bf2..aa96ffd33ca 100644
--- a/dlls/mf/session.c
+++ b/dlls/mf/session.c
@@ -147,6 +147,7 @@ struct transform_stream
 {
     struct list samples;
     unsigned int requests;
+    unsigned int min_buffer_size;
 };
 
 enum topo_node_flags
@@ -1258,11 +1259,19 @@ static HRESULT session_add_media_sink(struct media_session *session, IMFTopology
     return S_OK;
 }
 
+static unsigned int transform_node_get_stream_id(struct topo_node *node, BOOL output, unsigned int index)
+{
+    unsigned int *map = output ? node->u.transform.output_map : node->u.transform.input_map;
+    return map ? map[index] : index;
+}
+
 static HRESULT session_set_transform_stream_info(struct topo_node *node)
 {
     unsigned int *input_map = NULL, *output_map = NULL;
-    unsigned int i, input_count, output_count;
+    unsigned int i, input_count, output_count, block_alignment;
     struct transform_stream *streams;
+    IMFMediaType *media_type;
+    GUID major = { 0 };
     HRESULT hr;
 
     hr = IMFTransform_GetStreamCount(node->object.transform, &input_count, &output_count);
@@ -1282,20 +1291,33 @@ static HRESULT session_set_transform_stream_info(struct topo_node *node)
 
     if (SUCCEEDED(hr))
     {
+        node->u.transform.input_map = input_map;
+        node->u.transform.output_map = output_map;
+
         streams = heap_calloc(input_count, sizeof(*streams));
         for (i = 0; i < input_count; ++i)
             list_init(&streams[i].samples);
         node->u.transform.inputs = streams;
+        node->u.transform.input_count = input_count;
 
         streams = heap_calloc(output_count, sizeof(*streams));
         for (i = 0; i < output_count; ++i)
+        {
             list_init(&streams[i].samples);
-        node->u.transform.outputs = streams;
 
-        node->u.transform.input_count = input_count;
+            if (SUCCEEDED(IMFTransform_GetOutputCurrentType(node->object.transform,
+                    transform_node_get_stream_id(node, TRUE, i), &media_type)))
+            {
+                if (SUCCEEDED(IMFMediaType_GetMajorType(media_type, &major)) && IsEqualGUID(&major, &MFMediaType_Audio)
+                        && SUCCEEDED(IMFMediaType_GetUINT32(media_type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &block_alignment)))
+                {
+                    streams[i].min_buffer_size = block_alignment;
+                }
+                IMFMediaType_Release(media_type);
+            }
+        }
+        node->u.transform.outputs = streams;
         node->u.transform.output_count = output_count;
-        node->u.transform.input_map = input_map;
-        node->u.transform.output_map = output_map;
     }
 
     return hr;
@@ -2646,12 +2668,6 @@ static void session_set_sink_stream_state(struct media_session *session, IMFStre
     }
 }
 
-static DWORD transform_node_get_stream_id(struct topo_node *node, BOOL output, DWORD index)
-{
-    unsigned int *map = output ? node->u.transform.output_map : node->u.transform.input_map;
-    return map ? map[index] : index;
-}
-
 static struct sample *transform_create_sample(IMFSample *sample)
 {
     struct sample *sample_entry = heap_alloc_zero(sizeof(*sample_entry));
@@ -2669,8 +2685,8 @@ static struct sample *transform_create_sample(IMFSample *sample)
 static HRESULT transform_get_external_output_sample(const struct media_session *session, struct topo_node *transform,
         unsigned int output_index, const MFT_OUTPUT_STREAM_INFO *stream_info, IMFSample **sample)
 {
+    unsigned int buffer_size, downstream_input;
     IMFTopologyNode *downstream_node;
-    unsigned int downstream_input;
     IMFMediaBuffer *buffer = NULL;
     struct topo_node *topo_node;
     TOPOID node_id;
@@ -2693,7 +2709,9 @@ static HRESULT transform_get_external_output_sample(const struct media_session *
     }
     else
     {
-        hr = MFCreateAlignedMemoryBuffer(stream_info->cbSize, stream_info->cbAlignment, &buffer);
+        buffer_size = max(stream_info->cbSize, transform->u.transform.outputs[output_index].min_buffer_size);
+
+        hr = MFCreateAlignedMemoryBuffer(buffer_size, stream_info->cbAlignment, &buffer);
         if (SUCCEEDED(hr))
             hr = MFCreateSample(sample);
 




More information about the wine-cvs mailing list