[PATCH v3 7/7] winegstreamer: Expose output media type attributes from the stream format.

Rémi Bernon wine at gitlab.winehq.org
Mon May 23 11:38:26 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                | 17 +++++------
 dlls/winegstreamer/h264_decoder.c | 51 ++++++++++++++++---------------
 2 files changed, 34 insertions(+), 34 deletions(-)

diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index 419faa61e2b..3fe819ba23d 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -6841,7 +6841,7 @@ static void test_h264_decoder(void)
             ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video),
             ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_NV12),
             ATTR_RATIO(MF_MT_PIXEL_ASPECT_RATIO, 1, 1),
-            ATTR_RATIO(MF_MT_FRAME_RATE, 60000, 1000, .todo_value = TRUE),
+            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),
@@ -6855,7 +6855,7 @@ static void test_h264_decoder(void)
             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, .todo_value = TRUE),
+            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),
@@ -6869,7 +6869,7 @@ static void test_h264_decoder(void)
             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, .todo_value = TRUE),
+            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),
@@ -6883,7 +6883,7 @@ static void test_h264_decoder(void)
             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, .todo_value = TRUE),
+            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),
@@ -6897,7 +6897,7 @@ static void test_h264_decoder(void)
             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, .todo_value = TRUE),
+            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),
@@ -7206,7 +7206,6 @@ static void test_h264_decoder(void)
     hr = IMFTransform_GetOutputStreamInfo(transform, 0, &output_info);
     ok(hr == S_OK, "GetOutputStreamInfo returned %#lx\n", hr);
     ok(output_info.dwFlags == flags, "got dwFlags %#lx\n", output_info.dwFlags);
-    todo_wine
     ok(output_info.cbSize == actual_width * actual_height * 2, "got cbSize %#lx\n", output_info.cbSize);
     ok(output_info.cbAlignment == 0, "got cbAlignment %#lx\n", output_info.cbAlignment);
 
@@ -7248,14 +7247,12 @@ static void test_h264_decoder(void)
     memset(&output, 0, sizeof(output));
     output.pSample = create_sample(NULL, actual_width * actual_height * 2);
     hr = IMFTransform_ProcessOutput(transform, 0, 1, &output, &status);
-    todo_wine
     ok(hr == S_OK, "ProcessOutput returned %#lx\n", hr);
     ok(output.dwStreamID == 0, "got dwStreamID %lu\n", output.dwStreamID);
     ok(!!output.pSample, "got pSample %p\n", output.pSample);
     ok(output.dwStatus == 0, "got dwStatus %#lx\n", output.dwStatus);
     ok(!output.pEvents, "got pEvents %p\n", output.pEvents);
     ok(status == 0, "got status %#lx\n", status);
-    if (hr != S_OK) goto skip_nv12_tests;
 
     hr = IMFSample_GetUINT32(sample, &MFSampleExtension_CleanPoint, &value);
     ok(hr == MF_E_ATTRIBUTENOTFOUND, "GetUINT32 MFSampleExtension_CleanPoint returned %#lx\n", hr);
@@ -7272,9 +7269,7 @@ static void test_h264_decoder(void)
 
     time = 0xdeadbeef;
     hr = IMFSample_GetSampleTime(output.pSample, &time);
-    todo_wine
     ok(hr == S_OK, "GetSampleTime returned %#lx\n", hr);
-    todo_wine
     ok(time == 0, "got time %I64d\n", time);
 
     /* doesn't matter what frame rate we've selected, duration is defined by the stream */
@@ -7289,7 +7284,9 @@ static void test_h264_decoder(void)
     ok(hr == S_OK, "ConvertToContiguousBuffer returned %#lx\n", hr);
     hr = IMFMediaBuffer_Lock(media_buffer, &data, NULL, &length);
     ok(hr == S_OK, "Lock returned %#lx\n", hr);
+    todo_wine
     ok(length == nv12_frame_len, "got length %lu\n", length);
+    if (length != nv12_frame_len) goto skip_nv12_tests;
 
     for (i = 0; i < actual_aperture.Area.cy; ++i)
     {
diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c
index db4c74d561e..739bd2bb9c4 100644
--- a/dlls/winegstreamer/h264_decoder.c
+++ b/dlls/winegstreamer/h264_decoder.c
@@ -90,8 +90,10 @@ static HRESULT try_create_wg_transform(struct h264_decoder *decoder)
     return S_OK;
 }
 
-static HRESULT fill_output_media_type(IMFMediaType *media_type, IMFMediaType *default_type)
+static HRESULT fill_output_media_type(struct h264_decoder *decoder, IMFMediaType *media_type)
 {
+    IMFMediaType *default_type = decoder->output_type;
+    struct wg_format *wg_format = &decoder->wg_format;
     UINT32 value, width, height;
     UINT64 ratio;
     GUID subtype;
@@ -102,8 +104,7 @@ static HRESULT fill_output_media_type(IMFMediaType *media_type, IMFMediaType *de
 
     if (FAILED(hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &ratio)))
     {
-        if (!default_type || FAILED(hr = IMFMediaType_GetUINT64(default_type, &MF_MT_FRAME_SIZE, &ratio)))
-            ratio = (UINT64)1920 << 32 | 1080;
+        ratio = (UINT64)wg_format->u.video.width << 32 | wg_format->u.video.height;
         if (FAILED(hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_SIZE, ratio)))
             return hr;
     }
@@ -112,24 +113,21 @@ static HRESULT fill_output_media_type(IMFMediaType *media_type, IMFMediaType *de
 
     if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_FRAME_RATE, NULL)))
     {
-        if (!default_type || FAILED(hr = IMFMediaType_GetUINT64(default_type, &MF_MT_FRAME_RATE, &ratio)))
-            ratio = (UINT64)30000 << 32 | 1001;
+        ratio = (UINT64)wg_format->u.video.fps_n << 32 | wg_format->u.video.fps_d;
         if (FAILED(hr = IMFMediaType_SetUINT64(media_type, &MF_MT_FRAME_RATE, ratio)))
             return hr;
     }
 
     if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_PIXEL_ASPECT_RATIO, NULL)))
     {
-        if (!default_type || FAILED(hr = IMFMediaType_GetUINT64(default_type, &MF_MT_PIXEL_ASPECT_RATIO, &ratio)))
-            ratio = (UINT64)1 << 32 | 1;
+        ratio = (UINT64)1 << 32 | 1; /* FIXME: read it from format */
         if (FAILED(hr = IMFMediaType_SetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, ratio)))
             return hr;
     }
 
     if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_SAMPLE_SIZE, NULL)))
     {
-        if ((!default_type || FAILED(hr = IMFMediaType_GetUINT32(default_type, &MF_MT_SAMPLE_SIZE, &value))) &&
-                FAILED(hr = MFCalculateImageSize(&subtype, width, height, &value)))
+        if (FAILED(hr = MFCalculateImageSize(&subtype, width, height, &value)))
             return hr;
         if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_SAMPLE_SIZE, value)))
             return hr;
@@ -137,8 +135,7 @@ static HRESULT fill_output_media_type(IMFMediaType *media_type, IMFMediaType *de
 
     if (FAILED(hr = IMFMediaType_GetItem(media_type, &MF_MT_DEFAULT_STRIDE, NULL)))
     {
-        if ((!default_type || FAILED(hr = IMFMediaType_GetUINT32(default_type, &MF_MT_DEFAULT_STRIDE, &value))) &&
-                FAILED(hr = MFGetStrideForBitmapInfoHeader(subtype.Data1, width, (LONG *)&value)))
+        if (FAILED(hr = MFGetStrideForBitmapInfoHeader(subtype.Data1, width, (LONG *)&value)))
             return hr;
         if (FAILED(hr = IMFMediaType_SetUINT32(media_type, &MF_MT_DEFAULT_STRIDE, value)))
             return hr;
@@ -273,23 +270,15 @@ static HRESULT WINAPI transform_GetInputStreamInfo(IMFTransform *iface, DWORD id
 static HRESULT WINAPI transform_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info)
 {
     struct h264_decoder *decoder = impl_from_IMFTransform(iface);
-    UINT32 sample_size;
-    UINT64 frame_size;
+    UINT32 actual_width, actual_height;
 
     TRACE("iface %p, id %#lx, info %p.\n", iface, id, info);
 
-    if (!decoder->output_type)
-        sample_size = 1920 * 1088 * 2;
-    else if (FAILED(IMFMediaType_GetUINT32(decoder->output_type, &MF_MT_SAMPLE_SIZE, &sample_size)))
-    {
-        if (FAILED(IMFMediaType_GetUINT64(decoder->output_type, &MF_MT_FRAME_SIZE, &frame_size)))
-            sample_size = 1920 * 1088 * 2;
-        else
-            sample_size = (frame_size >> 32) * (UINT32)frame_size * 2;
-    }
+    actual_width = (decoder->wg_format.u.video.width + 15) & ~15;
+    actual_height = (decoder->wg_format.u.video.height + 15) & ~15;
 
     info->dwFlags = MFT_OUTPUT_STREAM_WHOLE_SAMPLES | MFT_OUTPUT_STREAM_SINGLE_SAMPLE_PER_BUFFER | MFT_OUTPUT_STREAM_FIXED_SAMPLE_SIZE;
-    info->cbSize = sample_size;
+    info->cbSize = actual_width * actual_height * 2;
     info->cbAlignment = 0;
 
     return S_OK;
@@ -379,7 +368,7 @@ static HRESULT WINAPI transform_GetOutputAvailableType(IMFTransform *iface, DWOR
     if (FAILED(hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, output_type)))
         goto done;
 
-    hr = fill_output_media_type(media_type, NULL);
+    hr = fill_output_media_type(decoder, media_type);
 
 done:
     if (SUCCEEDED(hr))
@@ -545,6 +534,7 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags,
     MFT_OUTPUT_STREAM_INFO info;
     struct wg_sample *wg_sample;
     struct wg_format wg_format;
+    UINT64 frame_rate;
     HRESULT hr;
 
     TRACE("iface %p, flags %#lx, count %lu, samples %p, status %p.\n", iface, flags, count, samples, status);
@@ -572,6 +562,14 @@ static HRESULT WINAPI transform_ProcessOutput(IMFTransform *iface, DWORD flags,
         if (!wg_format_compare(&decoder->wg_format, &wg_format))
         {
             decoder->wg_format = wg_format;
+
+            /* keep the frame rate that was requested, GStreamer doesn't provide any */
+            if (SUCCEEDED(IMFMediaType_GetUINT64(decoder->output_type, &MF_MT_FRAME_RATE, &frame_rate)))
+            {
+                decoder->wg_format.u.video.fps_n = frame_rate >> 32;
+                decoder->wg_format.u.video.fps_d = (UINT32)frame_rate;
+            }
+
             samples[0].dwStatus |= MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE;
             *status |= MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE;
             hr = MF_E_TRANSFORM_STREAM_CHANGE;
@@ -647,6 +645,11 @@ HRESULT h264_decoder_create(REFIID riid, void **ret)
 
     decoder->IMFTransform_iface.lpVtbl = &transform_vtbl;
     decoder->refcount = 1;
+    decoder->wg_format.u.video.format = WG_VIDEO_FORMAT_UNKNOWN;
+    decoder->wg_format.u.video.width = 1920;
+    decoder->wg_format.u.video.height = 1080;
+    decoder->wg_format.u.video.fps_n = 30000;
+    decoder->wg_format.u.video.fps_d = 1001;
 
     *ret = &decoder->IMFTransform_iface;
     TRACE("Created decoder %p\n", *ret);
-- 
GitLab

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



More information about the wine-devel mailing list