[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