[PATCH v2 3/4] winegstreamer: Introduce new WG_MAJOR_TYPE_WMA major type.
Rémi Bernon
rbernon at codeweavers.com
Mon Feb 14 04:19:46 CST 2022
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>
---
dlls/winegstreamer/mfplat.c | 72 +++++++++++++++++++++++++++++-
dlls/winegstreamer/quartz_parser.c | 8 ++++
dlls/winegstreamer/unixlib.h | 12 +++++
dlls/winegstreamer/wg_format.c | 7 +++
dlls/winegstreamer/wm_reader.c | 8 ++++
dlls/winegstreamer/wma_decoder.c | 11 +++++
6 files changed, 116 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
index a111bbe196d..ccd1d400d2c 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -635,6 +635,10 @@ IMFMediaType *mf_media_type_from_wg_format(const struct wg_format *format)
case WG_MAJOR_TYPE_UNKNOWN:
return NULL;
+ case WG_MAJOR_TYPE_WMA:
+ FIXME("WMA format not implemented!\n");
+ return NULL;
+
case WG_MAJOR_TYPE_AUDIO:
return mf_media_type_from_wg_format_audio(format);
@@ -741,9 +745,57 @@ static void mf_media_type_to_wg_format_video(IMFMediaType *type, struct wg_forma
FIXME("Unrecognized video subtype %s.\n", debugstr_guid(&subtype));
}
+static void mf_media_type_to_wg_format_wma(IMFMediaType *type, struct wg_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->major_type = WG_MAJOR_TYPE_WMA;
+ format->u.wma.version = version;
+ format->u.wma.bitrate = bytes_per_second * 8;
+ format->u.wma.rate = rate;
+ format->u.wma.depth = depth;
+ format->u.wma.channels = channels;
+ format->u.wma.block_align = block_align;
+ format->u.wma.codec_data_len = codec_data_len;
+ memcpy(format->u.wma.codec_data, codec_data, codec_data_len);
+}
+
void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format)
{
- GUID major_type;
+ GUID major_type, subtype;
memset(format, 0, sizeof(*format));
@@ -752,9 +804,25 @@ void mf_media_type_to_wg_format(IMFMediaType *type, struct wg_format *format)
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))
- mf_media_type_to_wg_format_audio(type, format);
+ {
+ if (IsEqualGUID(&subtype, &MEDIASUBTYPE_MSAUDIO1))
+ mf_media_type_to_wg_format_wma(type, format, 1);
+ else if (IsEqualGUID(&subtype, &MFAudioFormat_WMAudioV8))
+ mf_media_type_to_wg_format_wma(type, format, 2);
+ else if (IsEqualGUID(&subtype, &MFAudioFormat_WMAudioV9))
+ mf_media_type_to_wg_format_wma(type, format, 3);
+ else if (IsEqualGUID(&subtype, &MFAudioFormat_WMAudio_Lossless))
+ mf_media_type_to_wg_format_wma(type, format, 4);
+ else
+ mf_media_type_to_wg_format_audio(type, format);
+ }
else if (IsEqualGUID(&major_type, &MFMediaType_Video))
mf_media_type_to_wg_format_video(type, format);
else
diff --git a/dlls/winegstreamer/quartz_parser.c b/dlls/winegstreamer/quartz_parser.c
index 45313ebda27..e06c55ccfe0 100644
--- a/dlls/winegstreamer/quartz_parser.c
+++ b/dlls/winegstreamer/quartz_parser.c
@@ -319,6 +319,10 @@ unsigned int wg_format_get_max_size(const struct wg_format *format)
break;
}
+ case WG_MAJOR_TYPE_WMA:
+ FIXME("WMA format not implemented!\n");
+ return 0;
+
case WG_MAJOR_TYPE_UNKNOWN:
FIXME("Cannot guess maximum sample size for unknown format.\n");
return 0;
@@ -413,6 +417,10 @@ bool amt_from_wg_format(AM_MEDIA_TYPE *mt, const struct wg_format *format, bool
case WG_MAJOR_TYPE_UNKNOWN:
return false;
+ case WG_MAJOR_TYPE_WMA:
+ FIXME("WMA format not implemented!\n");
+ return false;
+
case WG_MAJOR_TYPE_AUDIO:
return amt_from_wg_format_audio(mt, format);
diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h
index c8b98da3a64..8e3f5e84bfb 100644
--- a/dlls/winegstreamer/unixlib.h
+++ b/dlls/winegstreamer/unixlib.h
@@ -37,6 +37,7 @@ struct wg_format
WG_MAJOR_TYPE_UNKNOWN,
WG_MAJOR_TYPE_VIDEO,
WG_MAJOR_TYPE_AUDIO,
+ WG_MAJOR_TYPE_WMA,
} major_type;
union
@@ -88,6 +89,17 @@ struct wg_format
uint32_t channel_mask; /* In WinMM format. */
uint32_t rate;
} audio;
+ 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];
+ } wma;
} u;
};
diff --git a/dlls/winegstreamer/wg_format.c b/dlls/winegstreamer/wg_format.c
index 8952acc1c2e..8f771bb8abd 100644
--- a/dlls/winegstreamer/wg_format.c
+++ b/dlls/winegstreamer/wg_format.c
@@ -400,6 +400,9 @@ GstCaps *wg_format_to_caps(const struct wg_format *format)
{
case WG_MAJOR_TYPE_UNKNOWN:
return NULL;
+ case WG_MAJOR_TYPE_WMA:
+ GST_FIXME("WMA format not implemented!\n");
+ return NULL;
case WG_MAJOR_TYPE_AUDIO:
return wg_format_to_caps_audio(format);
case WG_MAJOR_TYPE_VIDEO:
@@ -419,6 +422,10 @@ bool wg_format_compare(const struct wg_format *a, const struct wg_format *b)
case WG_MAJOR_TYPE_UNKNOWN:
return false;
+ case WG_MAJOR_TYPE_WMA:
+ GST_FIXME("WMA format not implemented!\n");
+ return false;
+
case WG_MAJOR_TYPE_AUDIO:
return a->u.audio.format == b->u.audio.format
&& a->u.audio.channels == b->u.audio.channels
diff --git a/dlls/winegstreamer/wm_reader.c b/dlls/winegstreamer/wm_reader.c
index d40afb66afd..01518c6b9a8 100644
--- a/dlls/winegstreamer/wm_reader.c
+++ b/dlls/winegstreamer/wm_reader.c
@@ -1687,6 +1687,9 @@ HRESULT wm_reader_get_output_format_count(struct wm_reader *reader, DWORD output
*count = ARRAY_SIZE(video_formats);
break;
+ case WG_MAJOR_TYPE_WMA:
+ FIXME("WMA format not implemented!\n");
+ /* fallthrough */
case WG_MAJOR_TYPE_AUDIO:
case WG_MAJOR_TYPE_UNKNOWN:
*count = 1;
@@ -1733,6 +1736,9 @@ HRESULT wm_reader_get_output_format(struct wm_reader *reader, DWORD output,
format.u.audio.format = WG_AUDIO_FORMAT_S16LE;
break;
+ case WG_MAJOR_TYPE_WMA:
+ FIXME("WMA format not implemented!\n");
+ break;
case WG_MAJOR_TYPE_UNKNOWN:
break;
}
@@ -1808,6 +1814,8 @@ static const char *get_major_type_string(enum wg_major_type type)
return "video";
case WG_MAJOR_TYPE_UNKNOWN:
return "unknown";
+ case WG_MAJOR_TYPE_WMA:
+ return "wma";
}
assert(0);
return NULL;
diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c
index 3b051230a9e..b209ffc2e77 100644
--- a/dlls/winegstreamer/wma_decoder.c
+++ b/dlls/winegstreamer/wma_decoder.c
@@ -64,8 +64,19 @@ static inline struct wma_decoder *impl_from_IUnknown(IUnknown *iface)
static HRESULT try_create_wg_transform(struct wma_decoder *decoder)
{
+ struct wg_format input_format, output_format;
+
if (decoder->wg_transform)
wg_transform_destroy(decoder->wg_transform);
+ decoder->wg_transform = NULL;
+
+ mf_media_type_to_wg_format(decoder->input_type, &input_format);
+ if (input_format.major_type == WG_MAJOR_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