[PATCH 3/4] winegstreamer: Support mapping of MF_MT_MINIMUM_DISPLAY_APERTURE.

Rémi Bernon wine at gitlab.winehq.org
Fri May 27 03:23:17 CDT 2022


From: Rémi Bernon <rbernon at codeweavers.com>

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45988
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47084
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49715
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52183
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/mf/tests/mf.c                | 40 +++++++++++++++----------------
 dlls/winegstreamer/h264_decoder.c | 16 +++++++++++++
 dlls/winegstreamer/mfplat.c       | 25 +++++++++++++++++++
 dlls/winegstreamer/unixlib.h      |  1 +
 dlls/winegstreamer/wg_format.c    |  3 ++-
 dlls/winegstreamer/wg_transform.c | 23 ++++++++++++++++++
 6 files changed, 87 insertions(+), 21 deletions(-)

diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index 81bfafbda04..4f55a67f30b 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -6842,70 +6842,70 @@ static void test_h264_decoder(void)
             ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_NV12),
             ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1),
             ATTR_RATIO(MF_MT_FRAME_RATE, 60000, 1000),
-            ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height, .todo_value = TRUE),
-            ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 3 / 2, .todo_value = TRUE),
-            ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width, .todo_value = TRUE),
+            ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height),
+            ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 3 / 2),
+            ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width),
             /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
             ATTR_UINT32(MF_MT_INTERLACE_MODE, 7),
             ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1),
             ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1),
-            ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16, .todo = TRUE),
+            ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16),
         },
         {
             ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video),
             ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_YV12),
             ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1),
             ATTR_RATIO(MF_MT_FRAME_RATE, 60000, 1000),
-            ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height, .todo_value = TRUE),
-            ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 3 / 2, .todo_value = TRUE),
-            ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width, .todo_value = TRUE),
+            ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height),
+            ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 3 / 2),
+            ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width),
             /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
             ATTR_UINT32(MF_MT_INTERLACE_MODE, 7),
             ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1),
             ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1),
-            ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16, .todo = TRUE),
+            ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16),
         },
         {
             ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video),
             ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_IYUV),
             ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1),
             ATTR_RATIO(MF_MT_FRAME_RATE, 60000, 1000),
-            ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height, .todo_value = TRUE),
-            ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 3 / 2, .todo_value = TRUE),
-            ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width, .todo_value = TRUE),
+            ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height),
+            ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 3 / 2),
+            ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width),
             /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
             ATTR_UINT32(MF_MT_INTERLACE_MODE, 7),
             ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1),
             ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1),
-            ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16, .todo = TRUE),
+            ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16),
         },
         {
             ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video),
             ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_I420),
             ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1),
             ATTR_RATIO(MF_MT_FRAME_RATE, 60000, 1000),
-            ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height, .todo_value = TRUE),
-            ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 3 / 2, .todo_value = TRUE),
-            ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width, .todo_value = TRUE),
+            ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height),
+            ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 3 / 2),
+            ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width),
             /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
             ATTR_UINT32(MF_MT_INTERLACE_MODE, 7),
             ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1),
             ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1),
-            ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16, .todo = TRUE),
+            ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16),
         },
         {
             ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video),
             ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_YUY2),
             ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1),
             ATTR_RATIO(MF_MT_FRAME_RATE, 60000, 1000),
-            ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height, .todo_value = TRUE),
-            ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 2, .todo_value = TRUE),
-            ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width * 2, .todo_value = TRUE),
+            ATTR_RATIO(MF_MT_FRAME_SIZE, actual_width, actual_height),
+            ATTR_UINT32(MF_MT_SAMPLE_SIZE, actual_width * actual_height * 2),
+            ATTR_UINT32(MF_MT_DEFAULT_STRIDE, actual_width * 2),
             /* ATTR_UINT32(MF_MT_VIDEO_ROTATION, 0), missing on Win7 */
             ATTR_UINT32(MF_MT_INTERLACE_MODE, 7),
             ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1),
             ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1),
-            ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16, .todo = TRUE),
+            ATTR_BLOB(MF_MT_MINIMUM_DISPLAY_APERTURE, &actual_aperture, 16),
         },
     };
 
diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c
index f97b6cf18c2..e39b9340be1 100644
--- a/dlls/winegstreamer/h264_decoder.c
+++ b/dlls/winegstreamer/h264_decoder.c
@@ -173,6 +173,22 @@ static HRESULT fill_output_media_type(struct h264_decoder *decoder, IMFMediaType
             return hr;
     }
 
+    if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, NULL))
+            && !IsRectEmpty(&wg_format->u.video.padding))
+    {
+        MFVideoArea aperture =
+        {
+            .OffsetX = {.value = wg_format->u.video.padding.left},
+            .OffsetY = {.value = wg_format->u.video.padding.top},
+            .Area.cx = wg_format->u.video.width - wg_format->u.video.padding.right - wg_format->u.video.padding.left,
+            .Area.cy = wg_format->u.video.height - wg_format->u.video.padding.bottom - wg_format->u.video.padding.top,
+        };
+
+        if (FAILED(hr = IMFMediaType_SetBlob(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE,
+                (BYTE *)&aperture, sizeof(aperture))))
+            return hr;
+    }
+
     return S_OK;
 }
 
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
index 2e53afb0542..0226e7a2e45 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -688,6 +688,20 @@ static IMFMediaType *mf_media_type_from_wg_format_video(const struct wg_format *
             IMFMediaType_SetUINT32(type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
             IMFMediaType_SetUINT32(type, &MF_MT_VIDEO_ROTATION, MFVideoRotationFormat_0);
 
+            if (!IsRectEmpty(&format->u.video.padding))
+            {
+                MFVideoArea aperture =
+                {
+                    .OffsetX = {.value = format->u.video.padding.left},
+                    .OffsetY = {.value = format->u.video.padding.top},
+                    .Area.cx = format->u.video.width - format->u.video.padding.right - format->u.video.padding.left,
+                    .Area.cy = format->u.video.height - format->u.video.padding.bottom - format->u.video.padding.top,
+                };
+
+                IMFMediaType_SetBlob(type, &MF_MT_MINIMUM_DISPLAY_APERTURE,
+                        (BYTE *)&aperture, sizeof(aperture));
+            }
+
             return type;
         }
     }
@@ -770,7 +784,9 @@ static void mf_media_type_to_wg_format_audio(IMFMediaType *type, const GUID *sub
 static void mf_media_type_to_wg_format_video(IMFMediaType *type, const GUID *subtype, struct wg_format *format)
 {
     UINT64 frame_rate, frame_size;
+    MFVideoArea aperture;
     unsigned int i;
+    UINT32 size;
 
     if (FAILED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_SIZE, &frame_size)))
     {
@@ -784,6 +800,15 @@ static void mf_media_type_to_wg_format_video(IMFMediaType *type, const GUID *sub
     format->u.video.fps_n = 1;
     format->u.video.fps_d = 1;
 
+    if (SUCCEEDED(IMFMediaType_GetBlob(type, &MF_MT_MINIMUM_DISPLAY_APERTURE, (BYTE *)&aperture,
+            sizeof(aperture), &size)) && size == sizeof(aperture))
+    {
+        format->u.video.padding.left = aperture.OffsetX.value;
+        format->u.video.padding.top = aperture.OffsetY.value;
+        format->u.video.padding.right = format->u.video.width - aperture.Area.cx - aperture.OffsetX.value;
+        format->u.video.padding.bottom = format->u.video.height - aperture.Area.cy - aperture.OffsetY.value;
+    }
+
     if (SUCCEEDED(IMFMediaType_GetUINT64(type, &MF_MT_FRAME_RATE, &frame_rate)) && (UINT32)frame_rate)
     {
         format->u.video.fps_n = (UINT32)(frame_rate >> 32);
diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h
index e8cdfaf7217..f334a168bd1 100644
--- a/dlls/winegstreamer/unixlib.h
+++ b/dlls/winegstreamer/unixlib.h
@@ -68,6 +68,7 @@ struct wg_format
             } format;
             int32_t width, height;
             uint32_t fps_n, fps_d;
+            RECT padding;
         } video;
         struct
         {
diff --git a/dlls/winegstreamer/wg_format.c b/dlls/winegstreamer/wg_format.c
index 4cebeac9182..3b568ea2fec 100644
--- a/dlls/winegstreamer/wg_format.c
+++ b/dlls/winegstreamer/wg_format.c
@@ -552,7 +552,8 @@ bool wg_format_compare(const struct wg_format *a, const struct wg_format *b)
             /* Do not compare FPS. */
             return a->u.video.format == b->u.video.format
                     && a->u.video.width == b->u.video.width
-                    && abs(a->u.video.height) == abs(b->u.video.height);
+                    && abs(a->u.video.height) == abs(b->u.video.height)
+                    && EqualRect( &a->u.video.padding, &b->u.video.padding );
     }
 
     assert(0);
diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c
index 447639342ae..9a5a70d3d39 100644
--- a/dlls/winegstreamer/wg_transform.c
+++ b/dlls/winegstreamer/wg_transform.c
@@ -695,8 +695,31 @@ NTSTATUS wg_transform_read_data(void *args)
         gst_sample_set_info(transform->output_sample, NULL);
 
         if (format)
+        {
+            gsize plane_align = transform->output_plane_align;
+            GstVideoAlignment align;
+            GstVideoInfo info;
+
             wg_format_from_caps(format, output_caps);
 
+            if (format->major_type == WG_MAJOR_TYPE_VIDEO
+                    && gst_video_info_from_caps(&info, output_caps)
+                    && align_video_info_planes(plane_align, &info, &align))
+            {
+                GST_INFO("Returning video alignment left %u, top %u, right %u, bottom %u.", align.padding_left,
+                        align.padding_top, align.padding_right, align.padding_bottom);
+
+                format->u.video.padding.left = align.padding_left;
+                format->u.video.width += format->u.video.padding.left;
+                format->u.video.padding.right = align.padding_right;
+                format->u.video.width += format->u.video.padding.right;
+                format->u.video.padding.top = align.padding_top;
+                format->u.video.height += format->u.video.padding.top;
+                format->u.video.padding.bottom = align.padding_bottom;
+                format->u.video.height += format->u.video.padding.bottom;
+            }
+        }
+
         params->result = MF_E_TRANSFORM_STREAM_CHANGE;
         GST_INFO("Format changed detected, returning no output");
         return STATUS_SUCCESS;
-- 
GitLab


https://gitlab.winehq.org/wine/wine/-/merge_requests/139



More information about the wine-devel mailing list