[PATCH 2/3] winegstreamer: Introduce new wg_encoded_format struct.

Rémi Bernon rbernon at codeweavers.com
Fri Feb 11 03:36:20 CST 2022


And use it for decoder transform input types.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51931
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52391
Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---

This uses a separate struct for encoded formats, as I believe it was
suggested at some point (or I may be mistaken), but I'm not sure it's
best. If we intend to support encoders or converters in the wg_transform
the formats would need to be swapped, and in which case using the same
struct may be cleaner.

In that case, maybe using a separate major type for encoded formats, or
a separate major type for each encoded format would be better.

 dlls/winegstreamer/gst_private.h |  1 +
 dlls/winegstreamer/mfplat.c      | 84 ++++++++++++++++++++++++++++++++
 dlls/winegstreamer/unixlib.h     | 25 ++++++++++
 dlls/winegstreamer/wma_decoder.c | 12 +++++
 4 files changed, 122 insertions(+)

diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index df82b229143..cec52e976ec 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -117,6 +117,7 @@ extern HRESULT mfplat_DllRegisterServer(void) DECLSPEC_HIDDEN;
 
 IMFMediaType *mf_media_type_from_wg_format(const struct wg_format *format) DECLSPEC_HIDDEN;
 void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format) DECLSPEC_HIDDEN;
+void mf_media_type_to_wg_encoded_format(IMFMediaType *type, struct wg_encoded_format *format) DECLSPEC_HIDDEN;
 
 HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
 
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
index a111bbe196d..61c7fe28a63 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -760,3 +760,87 @@ void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format)
     else
         FIXME("Unrecognized major type %s.\n", debugstr_guid(&major_type));
 }
+
+static void mf_media_type_to_wg_encoded_format_wma(IMFMediaType *type, struct wg_encoded_format *format,
+        UINT32 version)
+{
+    UINT32 rate, depth, channels, block_align, bytes_per_second, codec_data_len;
+    BYTE codec_data[64];
+
+    if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &rate)))
+    {
+        FIXME("Sample rate is not set.\n");
+        return;
+    }
+    if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &channels)))
+    {
+        FIXME("Channel count is not set.\n");
+        return;
+    }
+    if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BLOCK_ALIGNMENT, &block_align)))
+    {
+        FIXME("Block alignment is not set.\n");
+        return;
+    }
+    if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &depth)))
+    {
+        FIXME("Depth is not set.\n");
+        return;
+    }
+    if (FAILED(IMFMediaType_GetBlob(type, &MF_MT_USER_DATA, codec_data, sizeof(codec_data), &codec_data_len)))
+    {
+        FIXME("Codec data is not set.\n");
+        return;
+    }
+    if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, &bytes_per_second)))
+    {
+        FIXME("Bitrate is not set.\n");
+        bytes_per_second = 0;
+    }
+
+    format->encoded_type = WG_ENCODED_TYPE_WMA;
+    format->u.xwma.version = version;
+    format->u.xwma.bitrate = bytes_per_second * 8;
+    format->u.xwma.rate = rate;
+    format->u.xwma.depth = depth;
+    format->u.xwma.channels = channels;
+    format->u.xwma.block_align = block_align;
+    format->u.xwma.codec_data_len = codec_data_len;
+    memcpy(format->u.xwma.codec_data, codec_data, codec_data_len);
+}
+
+void mf_media_type_to_wg_encoded_format(IMFMediaType *type, struct wg_encoded_format *format)
+{
+    GUID major_type, subtype;
+
+    memset(format, 0, sizeof(*format));
+
+    if (FAILED(IMFMediaType_GetMajorType(type, &major_type)))
+    {
+        FIXME("Major type is not set.\n");
+        return;
+    }
+    if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype)))
+    {
+        FIXME("Subtype is not set.\n");
+        return;
+    }
+
+    if (IsEqualGUID(&major_type, &MFMediaType_Audio))
+    {
+        if (IsEqualGUID(&subtype, &MEDIASUBTYPE_MSAUDIO1))
+            mf_media_type_to_wg_encoded_format_wma(type, format, 1);
+        else if (IsEqualGUID(&subtype, &MFAudioFormat_WMAudioV8))
+            mf_media_type_to_wg_encoded_format_wma(type, format, 2);
+        else if (IsEqualGUID(&subtype, &MFAudioFormat_WMAudioV9))
+            mf_media_type_to_wg_encoded_format_wma(type, format, 3);
+        else if (IsEqualGUID(&subtype, &MFAudioFormat_WMAudio_Lossless))
+            mf_media_type_to_wg_encoded_format_wma(type, format, 4);
+        else
+            FIXME("Unimplemented audio subtype %s.\n", debugstr_guid(&subtype));
+    }
+    else
+    {
+        FIXME("Unimplemented major type %s.\n", debugstr_guid(&major_type));
+    }
+}
diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h
index c8b98da3a64..ea46de4cce1 100644
--- a/dlls/winegstreamer/unixlib.h
+++ b/dlls/winegstreamer/unixlib.h
@@ -91,6 +91,31 @@ struct wg_format
     } u;
 };
 
+struct wg_encoded_format
+{
+    enum wg_encoded_type
+    {
+        WG_ENCODED_TYPE_UNKNOWN,
+        WG_ENCODED_TYPE_WMA,
+        WG_ENCODED_TYPE_XMA,
+    } encoded_type;
+
+    union
+    {
+        struct
+        {
+            uint32_t version;
+            uint32_t bitrate;
+            uint32_t rate;
+            uint32_t depth;
+            uint32_t channels;
+            uint32_t block_align;
+            uint32_t codec_data_len;
+            unsigned char codec_data[64];
+        } xwma;
+    } u;
+};
+
 enum wg_parser_event_type
 {
     WG_PARSER_EVENT_NONE = 0,
diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c
index 3b051230a9e..b037795fc78 100644
--- a/dlls/winegstreamer/wma_decoder.c
+++ b/dlls/winegstreamer/wma_decoder.c
@@ -64,8 +64,20 @@ static inline struct wma_decoder *impl_from_IUnknown(IUnknown *iface)
 
 static HRESULT try_create_wg_transform(struct wma_decoder *decoder)
 {
+    struct wg_encoded_format input_format;
+    struct wg_format output_format;
+
     if (decoder->wg_transform)
         wg_transform_destroy(decoder->wg_transform);
+    decoder->wg_transform = NULL;
+
+    mf_media_type_to_wg_encoded_format(decoder->input_type, &input_format);
+    if (input_format.encoded_type == WG_ENCODED_TYPE_UNKNOWN)
+        return MF_E_INVALIDMEDIATYPE;
+
+    mf_media_type_to_wg_format(decoder->output_type, &output_format);
+    if (output_format.major_type == WG_MAJOR_TYPE_UNKNOWN)
+        return MF_E_INVALIDMEDIATYPE;
 
     decoder->wg_transform = wg_transform_create();
     if (decoder->wg_transform)
-- 
2.34.1




More information about the wine-devel mailing list