[PATCH] winegstreamer: Check whether transforms are supported at creation time.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52908 Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52914 Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com> --- dlls/winegstreamer/h264_decoder.c | 10 ++++++++++ dlls/winegstreamer/wg_transform.c | 13 +++++++++---- dlls/winegstreamer/wma_decoder.c | 10 ++++++++++ 3 files changed, 29 insertions(+), 4 deletions(-) diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c index 8bfa15529db..778729f576c 100644 --- a/dlls/winegstreamer/h264_decoder.c +++ b/dlls/winegstreamer/h264_decoder.c @@ -585,10 +585,20 @@ static const IMFTransformVtbl transform_vtbl = HRESULT h264_decoder_create(REFIID riid, void **ret) { + struct wg_format output_format = {.major_type = WG_MAJOR_TYPE_UNKNOWN}; + struct wg_format input_format = {.major_type = WG_MAJOR_TYPE_H264}; + struct wg_transform *transform; struct h264_decoder *decoder; TRACE("riid %s, ret %p.\n", debugstr_guid(riid), ret); + if (!(transform = wg_transform_create(&input_format, &output_format))) + { + FIXME("GStreamer doesn't support H264 decoding, please install appropriate plugins\n"); + return E_FAIL; + } + wg_transform_destroy(transform); + if (!(decoder = calloc(1, sizeof(*decoder)))) return E_OUTOFMEMORY; diff --git a/dlls/winegstreamer/wg_transform.c b/dlls/winegstreamer/wg_transform.c index 49c7bfaa927..0b975a8210e 100644 --- a/dlls/winegstreamer/wg_transform.c +++ b/dlls/winegstreamer/wg_transform.c @@ -169,7 +169,6 @@ NTSTATUS wg_transform_create(void *args) NTSTATUS status = STATUS_UNSUCCESSFUL; GstPadTemplate *template = NULL; struct wg_transform *transform; - const gchar *media_type; GstEvent *event; if (!init_gstreamer()) @@ -210,9 +209,13 @@ NTSTATUS wg_transform_create(void *args) * based on the actual output caps now. Matching decoders with the * raw output media type should be enough. */ - media_type = gst_structure_get_name(gst_caps_get_structure(sink_caps, 0)); - if (!(raw_caps = gst_caps_new_empty_simple(media_type))) + if (!(raw_caps = gst_caps_new_any())) goto out; + if (gst_caps_get_size(sink_caps)) + { + const gchar *media_type = gst_structure_get_name(gst_caps_get_structure(sink_caps, 0)); + gst_caps_append_structure(raw_caps, gst_structure_new_empty(media_type)); + } switch (input_format.major_type) { @@ -268,9 +271,11 @@ NTSTATUS wg_transform_create(void *args) case WG_MAJOR_TYPE_H264: case WG_MAJOR_TYPE_WMA: - case WG_MAJOR_TYPE_UNKNOWN: GST_FIXME("Format %u not implemented!", output_format.major_type); goto out; + + case WG_MAJOR_TYPE_UNKNOWN: + break; } if (!(transform->their_sink = gst_element_get_static_pad(first, "sink"))) diff --git a/dlls/winegstreamer/wma_decoder.c b/dlls/winegstreamer/wma_decoder.c index 57b0f204f9e..9d1ad20fba7 100644 --- a/dlls/winegstreamer/wma_decoder.c +++ b/dlls/winegstreamer/wma_decoder.c @@ -853,10 +853,20 @@ static const IPropertyBagVtbl property_bag_vtbl = HRESULT wma_decoder_create(IUnknown *outer, IUnknown **out) { + struct wg_format output_format = {.major_type = WG_MAJOR_TYPE_UNKNOWN}; + struct wg_format input_format = {.major_type = WG_MAJOR_TYPE_WMA}; + struct wg_transform *transform; struct wma_decoder *decoder; TRACE("outer %p, out %p.\n", outer, out); + if (!(transform = wg_transform_create(&input_format, &output_format))) + { + FIXME("GStreamer doesn't support WMA decoding, please install appropriate plugins\n"); + return E_FAIL; + } + wg_transform_destroy(transform); + if (!(decoder = calloc(1, sizeof(*decoder)))) return E_OUTOFMEMORY; -- 2.35.1
On 4/27/22 12:50, Rémi Bernon wrote:
diff --git a/dlls/winegstreamer/h264_decoder.c b/dlls/winegstreamer/h264_decoder.c index 8bfa15529db..778729f576c 100644 --- a/dlls/winegstreamer/h264_decoder.c +++ b/dlls/winegstreamer/h264_decoder.c @@ -585,10 +585,20 @@ static const IMFTransformVtbl transform_vtbl =
HRESULT h264_decoder_create(REFIID riid, void **ret) { + struct wg_format output_format = {.major_type = WG_MAJOR_TYPE_UNKNOWN}; + struct wg_format input_format = {.major_type = WG_MAJOR_TYPE_H264};
This feels a bit awkward. input_format is somewhat ill-formed [not that struct wg_format is highly formalized, but wg_format_to_caps_h264() at least expects the profile and level to be set], but output_format has a major type of UNKNOWN, presumably to avoid passing an ill-formed type.
@@ -210,9 +209,13 @@ NTSTATUS wg_transform_create(void *args) * based on the actual output caps now. Matching decoders with the * raw output media type should be enough. */ - media_type = gst_structure_get_name(gst_caps_get_structure(sink_caps, 0)); - if (!(raw_caps = gst_caps_new_empty_simple(media_type))) + if (!(raw_caps = gst_caps_new_any())) goto out; + if (gst_caps_get_size(sink_caps)) + { + const gchar *media_type = gst_structure_get_name(gst_caps_get_structure(sink_caps, 0)); + gst_caps_append_structure(raw_caps, gst_structure_new_empty(media_type)); + }
And this will end up checking whether H.264 or WMA can decode to *anything*, which, while probably sufficient in practice, is less useful in theory than checking whether it can decode to, say, NV12 or PCM respectively. I don't think that wg_format structs need to be fully specified (e.g. just enough to calculate the GstStructure name seems sufficient), although it'd be nice to avoid generating GStreamer FIXMEs under normal operation.
participants (2)
-
Rémi Bernon -
Zebediah Figura