Zebediah Figura : winegstreamer: Implement IWMOutputMediaProps::GetMediaType().

Alexandre Julliard julliard at winehq.org
Thu Oct 28 16:07:45 CDT 2021


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

Author: Zebediah Figura <zfigura at codeweavers.com>
Date:   Thu Oct 28 11:45:58 2021 -0500

winegstreamer: Implement IWMOutputMediaProps::GetMediaType().

Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/winegstreamer/wm_reader.c | 49 ++++++++++++++++++++++++++++++++++++++----
 dlls/wmvcore/tests/wmvcore.c   | 27 +++++++++++------------
 2 files changed, 57 insertions(+), 19 deletions(-)

diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c
index 2a93e6e1d35..cd08bc96869 100644
--- a/dlls/winegstreamer/wm_reader.c
+++ b/dlls/winegstreamer/wm_reader.c
@@ -32,6 +32,8 @@ struct output_props
 {
     IWMOutputMediaProps IWMOutputMediaProps_iface;
     LONG refcount;
+
+    AM_MEDIA_TYPE mt;
 };
 
 static inline struct output_props *impl_from_IWMOutputMediaProps(IWMOutputMediaProps *iface)
@@ -89,8 +91,23 @@ static HRESULT WINAPI output_props_GetType(IWMOutputMediaProps *iface, GUID *maj
 
 static HRESULT WINAPI output_props_GetMediaType(IWMOutputMediaProps *iface, WM_MEDIA_TYPE *mt, DWORD *size)
 {
-    FIXME("iface %p, mt %p, size %p, stub!\n", iface, mt, size);
-    return E_NOTIMPL;
+    const struct output_props *props = impl_from_IWMOutputMediaProps(iface);
+    const DWORD req_size = *size;
+
+    TRACE("iface %p, mt %p, size %p.\n", iface, mt, size);
+
+    *size = sizeof(*mt) + props->mt.cbFormat;
+    if (!mt)
+        return S_OK;
+    if (req_size < *size)
+        return ASF_E_BUFFERTOOSMALL;
+
+    strmbase_dump_media_type(&props->mt);
+
+    memcpy(mt, &props->mt, sizeof(*mt));
+    memcpy(mt + 1, props->mt.pbFormat, props->mt.cbFormat);
+    mt->pbFormat = (BYTE *)(mt + 1);
+    return S_OK;
 }
 
 static HRESULT WINAPI output_props_SetMediaType(IWMOutputMediaProps *iface, WM_MEDIA_TYPE *mt)
@@ -123,7 +140,7 @@ static const struct IWMOutputMediaPropsVtbl output_props_vtbl =
     output_props_GetConnectionName,
 };
 
-static IWMOutputMediaProps *output_props_create(void)
+static IWMOutputMediaProps *output_props_create(const struct wg_format *format)
 {
     struct output_props *object;
 
@@ -132,6 +149,12 @@ static IWMOutputMediaProps *output_props_create(void)
     object->IWMOutputMediaProps_iface.lpVtbl = &output_props_vtbl;
     object->refcount = 1;
 
+    if (!amt_from_wg_format(&object->mt, format))
+    {
+        free(object);
+        return NULL;
+    }
+
     TRACE("Created output properties %p.\n", object);
     return &object->IWMOutputMediaProps_iface;
 }
@@ -1182,6 +1205,24 @@ HRESULT wm_reader_open_stream(struct wm_reader *reader, IStream *stream)
         stream->reader = reader;
         stream->index = i;
         wg_parser_stream_get_preferred_format(stream->wg_stream, &stream->format);
+        if (stream->format.major_type == WG_MAJOR_TYPE_AUDIO)
+        {
+            /* R.U.S.E enumerates available audio types, picks the first one it
+             * likes, and then sets the wrong stream to that type. libav might
+             * give us WG_AUDIO_FORMAT_F32LE by default, which will result in
+             * the game incorrectly interpreting float data as integer.
+             * Therefore just match native and always set our default format to
+             * S16LE. */
+            stream->format.u.audio.format = WG_AUDIO_FORMAT_S16LE;
+        }
+        else if (stream->format.major_type == WG_MAJOR_TYPE_VIDEO)
+        {
+            /* Call of Juarez: Bound in Blood breaks if I420 is enumerated.
+             * Some native decoders output I420, but the msmpeg4v3 decoder
+             * never does. */
+            if (stream->format.u.video.format == WG_VIDEO_FORMAT_I420)
+                stream->format.u.video.format = WG_VIDEO_FORMAT_YV12;
+        }
     }
 
     LeaveCriticalSection(&reader->cs);
@@ -1244,7 +1285,7 @@ HRESULT wm_reader_get_output_props(struct wm_reader *reader, DWORD output, IWMOu
         return E_INVALIDARG;
     }
 
-    *props = output_props_create();
+    *props = output_props_create(&stream->format);
     LeaveCriticalSection(&reader->cs);
     return *props ? S_OK : E_OUTOFMEMORY;
 }
diff --git a/dlls/wmvcore/tests/wmvcore.c b/dlls/wmvcore/tests/wmvcore.c
index 22184c98dc5..6fc74b62dba 100644
--- a/dlls/wmvcore/tests/wmvcore.c
+++ b/dlls/wmvcore/tests/wmvcore.c
@@ -728,24 +728,21 @@ static void test_sync_reader_types(void)
 
         ret_size = sizeof(mt_buffer);
         hr = IWMOutputMediaProps_GetMediaType(output_props, mt, &ret_size);
-        todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
+        ok(hr == S_OK, "Got hr %#x.\n", hr);
 
         ref = IWMOutputMediaProps_Release(output_props);
         ok(!ref, "Got outstanding refcount %d.\n", ref);
 
-        if (hr == S_OK)
+        if (IsEqualGUID(&majortype, &MEDIATYPE_Audio))
         {
-            if (IsEqualGUID(&majortype, &MEDIATYPE_Audio))
-            {
-                got_audio = true;
-                check_audio_type(mt);
-            }
-            else
-            {
-                ok(IsEqualGUID(&majortype, &MEDIATYPE_Video), "Got major type %s.\n", debugstr_guid(&majortype));
-                got_video = true;
-                check_video_type(mt);
-            }
+            got_audio = true;
+            check_audio_type(mt);
+        }
+        else
+        {
+            ok(IsEqualGUID(&majortype, &MEDIATYPE_Video), "Got major type %s.\n", debugstr_guid(&majortype));
+            got_video = true;
+            check_video_type(mt);
         }
 
         count = 0;
@@ -844,8 +841,8 @@ static void test_sync_reader_types(void)
         winetest_pop_context();
     }
 
-    todo_wine ok(got_audio, "No audio stream was enumerated.\n");
-    todo_wine ok(got_video, "No video stream was enumerated.\n");
+    ok(got_audio, "No audio stream was enumerated.\n");
+    ok(got_video, "No video stream was enumerated.\n");
 
     count = 0xdeadbeef;
     hr = IWMSyncReader_GetOutputFormatCount(reader, 2, &count);




More information about the wine-cvs mailing list