Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/gstdemux.c | 57 +++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index 82801900a15..0389edc4c13 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -686,6 +686,57 @@ static bool amt_to_wg_format_audio(const AM_MEDIA_TYPE *mt, struct wg_format *fo return false; }
+static bool amt_to_wg_format_audio_mpeg1(const AM_MEDIA_TYPE *mt, struct wg_format *format) +{ + const MPEG1WAVEFORMAT *audio_format = (const MPEG1WAVEFORMAT *)mt->pbFormat; + + if (!IsEqualGUID(&mt->formattype, &FORMAT_WaveFormatEx)) + { + FIXME("Unknown format type %s.\n", debugstr_guid(&mt->formattype)); + return false; + } + if (mt->cbFormat < sizeof(*audio_format) || !mt->pbFormat) + { + ERR("Unexpected format size %u.\n", mt->cbFormat); + return false; + } + + format->major_type = WG_MAJOR_TYPE_AUDIO; + format->u.audio.channels = audio_format->wfx.nChannels; + format->u.audio.rate = audio_format->wfx.nSamplesPerSec; + if (audio_format->fwHeadLayer == 1) + format->u.audio.format = WG_AUDIO_FORMAT_MPEG1_LAYER1; + else if (audio_format->fwHeadLayer == 2) + format->u.audio.format = WG_AUDIO_FORMAT_MPEG1_LAYER2; + else if (audio_format->fwHeadLayer == 3) + format->u.audio.format = WG_AUDIO_FORMAT_MPEG1_LAYER3; + else + return false; + return true; +} + +static bool amt_to_wg_format_audio_mpeg1_layer3(const AM_MEDIA_TYPE *mt, struct wg_format *format) +{ + const MPEGLAYER3WAVEFORMAT *audio_format = (const MPEGLAYER3WAVEFORMAT *)mt->pbFormat; + + if (!IsEqualGUID(&mt->formattype, &FORMAT_WaveFormatEx)) + { + FIXME("Unknown format type %s.\n", debugstr_guid(&mt->formattype)); + return false; + } + if (mt->cbFormat < sizeof(*audio_format) || !mt->pbFormat) + { + ERR("Unexpected format size %u.\n", mt->cbFormat); + return false; + } + + format->major_type = WG_MAJOR_TYPE_AUDIO; + format->u.audio.channels = audio_format->wfx.nChannels; + format->u.audio.rate = audio_format->wfx.nSamplesPerSec; + format->u.audio.format = WG_AUDIO_FORMAT_MPEG1_LAYER3; + return true; +} + static bool amt_to_wg_format_video(const AM_MEDIA_TYPE *mt, struct wg_format *format) { static const struct @@ -750,7 +801,13 @@ static bool amt_to_wg_format(const AM_MEDIA_TYPE *mt, struct wg_format *format) if (IsEqualGUID(&mt->majortype, &MEDIATYPE_Video)) return amt_to_wg_format_video(mt, format); if (IsEqualGUID(&mt->majortype, &MEDIATYPE_Audio)) + { + if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_MPEG1AudioPayload)) + return amt_to_wg_format_audio_mpeg1(mt, format); + if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_MP3)) + return amt_to_wg_format_audio_mpeg1_layer3(mt, format); return amt_to_wg_format_audio(mt, format); + }
FIXME("Unknown major type %s.\n", debugstr_guid(&mt->majortype)); return false;
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/gstdemux.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index 0389edc4c13..7c70041000c 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -104,7 +104,7 @@ struct wg_parser_stream { GstPad *their_src, *post_sink, *post_src, *my_sink; GstElement *flip; - struct wg_format preferred_format; + struct wg_format preferred_format, current_format;
pthread_cond_t event_cond, event_empty_cond; struct wg_parser_event event; @@ -2746,6 +2746,7 @@ static HRESULT WINAPI GSTOutPin_DecideBufferSize(struct strmbase_source *iface, struct wg_parser_stream *stream = pin->wg_stream; unsigned int buffer_size = 16384; ALLOCATOR_PROPERTIES ret_props; + bool ret;
if (IsEqualGUID(&pin->pin.pin.mt.formattype, &FORMAT_VideoInfo)) { @@ -2764,6 +2765,8 @@ static HRESULT WINAPI GSTOutPin_DecideBufferSize(struct strmbase_source *iface, buffer_size = format->nAvgBytesPerSec; }
+ ret = amt_to_wg_format(&pin->pin.pin.mt, &stream->current_format); + assert(ret); stream->enabled = true;
gst_pad_push_event(stream->my_sink, gst_event_new_reconfigure());
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/gstdemux.c | 71 ++++++++++++++--------------------- 1 file changed, 29 insertions(+), 42 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index 7c70041000c..51e7a5abef1 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -628,14 +628,6 @@ static bool amt_from_wg_format(AM_MEDIA_TYPE *mt, const struct wg_format *format return false; }
-static bool amt_from_gst_caps(const GstCaps *caps, AM_MEDIA_TYPE *mt) -{ - struct wg_format wg_format; - - wg_format_from_caps(&wg_format, caps); - return amt_from_wg_format(mt, &wg_format); -} - static bool amt_to_wg_format_audio(const AM_MEDIA_TYPE *mt, struct wg_format *format) { static const struct @@ -906,6 +898,32 @@ static GstCaps *amt_to_gst_caps(const AM_MEDIA_TYPE *mt) return wg_format_to_caps(&wg_format); }
+static bool wg_format_compare(const struct wg_format *a, const struct wg_format *b) +{ + if (a->major_type != b->major_type) + return false; + + switch (a->major_type) + { + case WG_MAJOR_TYPE_UNKNOWN: + return false; + + case WG_MAJOR_TYPE_AUDIO: + return a->u.audio.format == b->u.audio.format + && a->u.audio.channels == b->u.audio.channels + && a->u.audio.rate == b->u.audio.rate; + + case WG_MAJOR_TYPE_VIDEO: + return a->u.video.format == b->u.video.format + && a->u.video.width == b->u.video.width + && a->u.video.height == b->u.video.height + && a->u.video.fps_d * b->u.video.fps_n == a->u.video.fps_n * b->u.video.fps_d; + } + + assert(0); + return false; +} + static gboolean query_sink(GstPad *pad, GstObject *parent, GstQuery *query) { struct parser_source *pin = gst_pad_get_element_private(pad); @@ -941,8 +959,8 @@ static gboolean query_sink(GstPad *pad, GstObject *parent, GstQuery *query) } case GST_QUERY_ACCEPT_CAPS: { + struct wg_format format; gboolean ret = TRUE; - AM_MEDIA_TYPE mt; GstCaps *caps;
if (!stream->enabled) @@ -952,45 +970,14 @@ static gboolean query_sink(GstPad *pad, GstObject *parent, GstQuery *query) }
gst_query_parse_accept_caps(query, &caps); - if (!amt_from_gst_caps(caps, &mt)) - return FALSE; - - if (!IsEqualGUID(&mt.majortype, &pin->pin.pin.mt.majortype) - || !IsEqualGUID(&mt.subtype, &pin->pin.pin.mt.subtype) - || !IsEqualGUID(&mt.formattype, &pin->pin.pin.mt.formattype)) - ret = FALSE; - - if (IsEqualGUID(&mt.majortype, &MEDIATYPE_Video)) - { - const VIDEOINFOHEADER *req_vih = (VIDEOINFOHEADER *)mt.pbFormat; - const VIDEOINFOHEADER *our_vih = (VIDEOINFOHEADER *)pin->pin.pin.mt.pbFormat; - - if (req_vih->bmiHeader.biWidth != our_vih->bmiHeader.biWidth - || req_vih->bmiHeader.biHeight != our_vih->bmiHeader.biHeight - || req_vih->bmiHeader.biBitCount != our_vih->bmiHeader.biBitCount - || req_vih->bmiHeader.biCompression != our_vih->bmiHeader.biCompression) - ret = FALSE; - } - else if (IsEqualGUID(&mt.majortype, &MEDIATYPE_Audio)) - { - const WAVEFORMATEX *req_wfx = (WAVEFORMATEX *)mt.pbFormat; - const WAVEFORMATEX *our_wfx = (WAVEFORMATEX *)pin->pin.pin.mt.pbFormat; - - if (req_wfx->nChannels != our_wfx->nChannels - || req_wfx->nSamplesPerSec != our_wfx->nSamplesPerSec - || req_wfx->wBitsPerSample != our_wfx->wBitsPerSample) - ret = FALSE; - } - - FreeMediaType(&mt); - + wg_format_from_caps(&format, caps); + ret = wg_format_compare(&format, &stream->current_format); if (!ret && WARN_ON(gstreamer)) { gchar *str = gst_caps_to_string(caps); WARN("Rejecting caps "%s".\n", debugstr_a(str)); g_free(str); } - gst_query_set_accept_caps_result(query, ret); return TRUE; }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/gstdemux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index 51e7a5abef1..070e2eca7f7 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -940,7 +940,7 @@ static gboolean query_sink(GstPad *pad, GstObject *parent, GstQuery *query) gst_query_parse_caps(query, &filter);
if (stream->enabled) - caps = amt_to_gst_caps(&pin->pin.pin.mt); + caps = wg_format_to_caps(&stream->current_format); else caps = gst_caps_new_any(); if (!caps)
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/gstdemux.c | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index 070e2eca7f7..e6abc50e41b 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -889,15 +889,6 @@ static GstCaps *wg_format_to_caps(const struct wg_format *format) return NULL; }
-static GstCaps *amt_to_gst_caps(const AM_MEDIA_TYPE *mt) -{ - struct wg_format wg_format; - - if (!amt_to_wg_format(mt, &wg_format)) - return NULL; - return wg_format_to_caps(&wg_format); -} - static bool wg_format_compare(const struct wg_format *a, const struct wg_format *b) { if (a->major_type != b->major_type) @@ -2261,13 +2252,10 @@ static BOOL decodebin_parser_init_gst(struct parser *filter)
static HRESULT decodebin_parser_source_query_accept(struct parser_source *pin, const AM_MEDIA_TYPE *mt) { - /* At least make sure we can convert it to GstCaps. */ - GstCaps *caps = amt_to_gst_caps(mt); + struct wg_format format;
- if (!caps) - return S_FALSE; - gst_caps_unref(caps); - return S_OK; + /* At least make sure we can convert it to wg_format. */ + return amt_to_wg_format(mt, &format) ? S_OK : S_FALSE; }
static HRESULT decodebin_parser_source_get_media_type(struct parser_source *pin,
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/gstdemux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index e6abc50e41b..8fc1e8608a1 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -920,7 +920,7 @@ static gboolean query_sink(GstPad *pad, GstObject *parent, GstQuery *query) struct parser_source *pin = gst_pad_get_element_private(pad); struct wg_parser_stream *stream = pin->wg_stream;
- TRACE("pin %p, type "%s".\n", pin, gst_query_type_get_name(query->type)); + GST_LOG("pin %p, type "%s".", pin, gst_query_type_get_name(query->type));
switch (query->type) { @@ -966,7 +966,7 @@ static gboolean query_sink(GstPad *pad, GstObject *parent, GstQuery *query) if (!ret && WARN_ON(gstreamer)) { gchar *str = gst_caps_to_string(caps); - WARN("Rejecting caps "%s".\n", debugstr_a(str)); + GST_WARNING("Rejecting caps "%s".", str); g_free(str); } gst_query_set_accept_caps_result(query, ret);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/gst_cbs.c | 13 ------------- dlls/winegstreamer/gst_cbs.h | 8 -------- dlls/winegstreamer/gstdemux.c | 9 +-------- 3 files changed, 1 insertion(+), 29 deletions(-)
diff --git a/dlls/winegstreamer/gst_cbs.c b/dlls/winegstreamer/gst_cbs.c index 90c34b1cb39..312c12fd194 100644 --- a/dlls/winegstreamer/gst_cbs.c +++ b/dlls/winegstreamer/gst_cbs.c @@ -147,19 +147,6 @@ void existing_new_pad_wrapper(GstElement *bin, GstPad *pad, gpointer user) call_cb(&cbdata); }
-gboolean query_sink_wrapper(GstPad *pad, GstObject *parent, GstQuery *query) -{ - struct cb_data cbdata = { QUERY_SINK }; - - cbdata.u.query_sink_data.pad = pad; - cbdata.u.query_sink_data.parent = parent; - cbdata.u.query_sink_data.query = query; - - call_cb(&cbdata); - - return cbdata.u.query_sink_data.ret; -} - GstFlowReturn bytestream_wrapper_pull_wrapper(GstPad *pad, GstObject *parent, guint64 ofs, guint len, GstBuffer **buf) { diff --git a/dlls/winegstreamer/gst_cbs.h b/dlls/winegstreamer/gst_cbs.h index cbd9a630885..f6f1ffb526b 100644 --- a/dlls/winegstreamer/gst_cbs.h +++ b/dlls/winegstreamer/gst_cbs.h @@ -31,7 +31,6 @@ typedef enum {
enum CB_TYPE { EXISTING_NEW_PAD, - QUERY_SINK, GSTDEMUX_MAX, BYTESTREAM_WRAPPER_PULL, BYTESTREAM_QUERY, @@ -94,12 +93,6 @@ struct cb_data { GstPad *pad; gpointer user; } pad_removed_data; - struct query_sink_data { - GstPad *pad; - GstObject *parent; - GstQuery *query; - gboolean ret; - } query_sink_data; } u;
int finished; @@ -115,7 +108,6 @@ void perform_cb_media_source(struct cb_data *data) DECLSPEC_HIDDEN; void existing_new_pad_wrapper(GstElement *bin, GstPad *pad, gpointer user) DECLSPEC_HIDDEN; GstFlowReturn got_data_wrapper(GstPad *pad, GstObject *parent, GstBuffer *buf) DECLSPEC_HIDDEN; void Gstreamer_transform_pad_added_wrapper(GstElement *filter, GstPad *pad, gpointer user) DECLSPEC_HIDDEN; -gboolean query_sink_wrapper(GstPad *pad, GstObject *parent, GstQuery *query) DECLSPEC_HIDDEN; GstFlowReturn bytestream_wrapper_pull_wrapper(GstPad *pad, GstObject *parent, guint64 ofs, guint len, GstBuffer **buf) DECLSPEC_HIDDEN; gboolean bytestream_query_wrapper(GstPad *pad, GstObject *parent, GstQuery *query) DECLSPEC_HIDDEN; gboolean bytestream_pad_mode_activate_wrapper(GstPad *pad, GstObject *parent, GstPadMode mode, gboolean activate) DECLSPEC_HIDDEN; diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index 8fc1e8608a1..e1309e97c4c 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -2858,7 +2858,7 @@ static struct parser_source *create_pin(struct parser *filter, const WCHAR *name gst_pad_set_element_private(stream->my_sink, pin); gst_pad_set_chain_function(stream->my_sink, got_data_sink); gst_pad_set_event_function(stream->my_sink, event_sink); - gst_pad_set_query_function(stream->my_sink, query_sink_wrapper); + gst_pad_set_query_function(stream->my_sink, query_sink);
filter->sources[filter->source_count++] = pin; parser->streams[parser->stream_count++] = stream; @@ -2927,13 +2927,6 @@ void perform_cb_gstdemux(struct cb_data *cbdata) existing_new_pad(data->element, data->pad, data->user); break; } - case QUERY_SINK: - { - struct query_sink_data *data = &cbdata->u.query_sink_data; - cbdata->u.query_sink_data.ret = query_sink(data->pad, data->parent, - data->query); - break; - } default: { assert(0);