Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/gstdemux.c | 1 + 1 file changed, 1 insertion(+)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index 8213bfdb439..de508b4167b 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -169,6 +169,7 @@ static gboolean amt_from_gst_caps_audio_raw(const GstCaps *caps, AM_MEDIA_TYPE * wfe->dwChannelMask = 0; } if (GST_AUDIO_INFO_IS_FLOAT(&ainfo)) { + amt->subtype = MEDIASUBTYPE_IEEE_FLOAT; wfe->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; wfx->wBitsPerSample = wfe->Samples.wValidBitsPerSample = 32; } else {
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/gstdemux.c | 1 - 1 file changed, 1 deletion(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index de508b4167b..66557b63a59 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -171,7 +171,6 @@ static gboolean amt_from_gst_caps_audio_raw(const GstCaps *caps, AM_MEDIA_TYPE * if (GST_AUDIO_INFO_IS_FLOAT(&ainfo)) { amt->subtype = MEDIASUBTYPE_IEEE_FLOAT; wfe->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT; - wfx->wBitsPerSample = wfe->Samples.wValidBitsPerSample = 32; } else { wfe->SubFormat = KSDATAFORMAT_SUBTYPE_PCM; if (wfx->nChannels <= 2 && bpp <= 16 && depth == bpp) {
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/gstdemux.c | 155 +++++++++++++++++----------------- 1 file changed, 78 insertions(+), 77 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index 66557b63a59..8e36644030a 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -85,10 +85,7 @@ struct gstdemux_source struct strmbase_source pin; IQualityControl IQualityControl_iface;
- GstElement *flipfilter; - GstPad *flip_sink, *flip_src; - GstPad *their_src; - GstPad *my_sink; + GstPad *their_src, *post_sink, *post_src, *my_sink; AM_MEDIA_TYPE mt; HANDLE caps_event; GstSegment *segment; @@ -1004,11 +1001,10 @@ static void removed_decoded_pad(GstElement *bin, GstPad *pad, gpointer user)
if (pin->their_src == pad) { - if(pin->flipfilter) - gst_pad_unlink(pin->their_src, pin->flip_sink); + if (pin->post_sink) + gst_pad_unlink(pin->their_src, pin->post_sink); else gst_pad_unlink(pin->their_src, pin->my_sink); - gst_object_unref(pin->their_src); pin->their_src = NULL; return; @@ -1052,85 +1048,91 @@ static void init_new_decoded_pad(GstElement *bin, GstPad *pad, struct gstdemux *
if (!strcmp(typename, "video/x-raw")) { - GstElement *vconv; - - TRACE("setting up videoflip filter for pin %p, my_sink: %p, their_src: %p\n", - pin, pin->my_sink, pad); + GstElement *vconv, *flip;
- /* gstreamer outputs video top-down, but dshow expects bottom-up, so - * make new transform filter to invert video */ - vconv = gst_element_factory_make("videoconvert", NULL); - if(!vconv){ - ERR("Missing videoconvert filter?\n"); - ret = -1; - goto exit; + /* decodebin considers many YUV formats to be "raw", but some quartz + * filters can't handle those. Also, videoflip can't handle all "raw" + * formats either. Add a videoconvert to swap color spaces. */ + if (!(vconv = gst_element_factory_make("videoconvert", NULL))) + { + ERR("Failed to create videoconvert, are %u-bit GStreamer "base" plugins installed?\n", + 8 * (int)sizeof(void *)); + return; }
- pin->flipfilter = gst_element_factory_make("videoflip", NULL); - if(!pin->flipfilter){ - ERR("Missing videoflip filter?\n"); - ret = -1; - goto exit; + /* GStreamer outputs video top-down, but DirectShow expects bottom-up. */ + if (!(flip = gst_element_factory_make("videoflip", NULL))) + { + ERR("Failed to create videoflip, are %u-bit GStreamer "good" plugins installed?\n", + 8 * (int)sizeof(void *)); + return; }
- gst_util_set_object_arg(G_OBJECT(pin->flipfilter), "method", "vertical-flip"); + gst_util_set_object_arg(G_OBJECT(flip), "method", "vertical-flip");
gst_bin_add(GST_BIN(This->container), vconv); /* bin takes ownership */ gst_element_sync_state_with_parent(vconv); - gst_bin_add(GST_BIN(This->container), pin->flipfilter); /* bin takes ownership */ - gst_element_sync_state_with_parent(pin->flipfilter); + gst_bin_add(GST_BIN(This->container), flip); /* bin takes ownership */ + gst_element_sync_state_with_parent(flip);
- gst_element_link (vconv, pin->flipfilter); + gst_element_link(vconv, flip);
- pin->flip_sink = gst_element_get_static_pad(vconv, "sink"); - if(!pin->flip_sink){ - WARN("Couldn't find sink on flip filter\n"); - pin->flipfilter = NULL; - ret = -1; - goto exit; - } + pin->post_sink = gst_element_get_static_pad(vconv, "sink"); + pin->post_src = gst_element_get_static_pad(flip, "src"); + } + else if (!strcmp(typename, "audio/x-raw")) + { + GstElement *convert;
- ret = gst_pad_link(pad, pin->flip_sink); - if(ret < 0){ - WARN("gst_pad_link failed: %d\n", ret); - gst_object_unref(pin->flip_sink); - pin->flip_sink = NULL; - pin->flipfilter = NULL; - goto exit; + /* Currently our dsound can't handle 64-bit formats or all + * surround-sound configurations. Native dsound can't always handle + * 64-bit formats either. Add an audioconvert to allow changing bit + * depth and channel count. */ + if (!(convert = gst_element_factory_make("audioconvert", NULL))) + { + ERR("Failed to create audioconvert, are %u-bit GStreamer "base" plugins installed?\n", + 8 * (int)sizeof(void *)); + return; }
- pin->flip_src = gst_element_get_static_pad(pin->flipfilter, "src"); - if(!pin->flip_src){ - WARN("Couldn't find src on flip filter\n"); - gst_object_unref(pin->flip_sink); - pin->flip_sink = NULL; - pin->flipfilter = NULL; - ret = -1; - goto exit; + gst_bin_add(GST_BIN(This->container), convert); + gst_element_sync_state_with_parent(convert); + + pin->post_sink = gst_element_get_static_pad(convert, "sink"); + pin->post_src = gst_element_get_static_pad(convert, "src"); + } + + if (pin->post_sink) + { + if ((ret = gst_pad_link(pad, pin->post_sink)) < 0) + { + ERR("Failed to link decodebin source pad to post-processing elements, error %s.\n", + gst_pad_link_get_name(ret)); + gst_object_unref(pin->post_sink); + pin->post_sink = NULL; + return; }
- ret = gst_pad_link(pin->flip_src, pin->my_sink); - if(ret < 0){ - WARN("gst_pad_link failed: %d\n", ret); - gst_object_unref(pin->flip_src); - pin->flip_src = NULL; - gst_object_unref(pin->flip_sink); - pin->flip_sink = NULL; - pin->flipfilter = NULL; - goto exit; + if ((ret = gst_pad_link(pin->post_src, pin->my_sink)) < 0) + { + ERR("Failed to link post-processing elements to our sink pad, error %s.\n", + gst_pad_link_get_name(ret)); + gst_object_unref(pin->post_src); + pin->post_src = NULL; + gst_object_unref(pin->post_sink); + pin->post_sink = NULL; + return; } - } else - ret = gst_pad_link(pad, pin->my_sink); + } + else if ((ret = gst_pad_link(pad, pin->my_sink)) < 0) + { + ERR("Failed to link decodebin source pad to our sink pad, error %s.\n", + gst_pad_link_get_name(ret)); + return; + }
gst_pad_set_active(pin->my_sink, 1); - -exit: - TRACE("Linking: %i\n", ret); - - if (ret >= 0) { - pin->their_src = pad; - gst_object_ref(pin->their_src); - } + gst_object_ref(pin->their_src = pad); }
static void existing_new_pad(GstElement *bin, GstPad *pad, gpointer user) @@ -1156,8 +1158,8 @@ static void existing_new_pad(GstElement *bin, GstPad *pad, gpointer user) if (!pin->their_src) { gst_segment_init(pin->segment, GST_FORMAT_TIME);
- if (pin->flipfilter) - ret = gst_pad_link(pad, pin->flip_sink); + if (pin->post_sink) + ret = gst_pad_link(pad, pin->post_sink); else ret = gst_pad_link(pad, pin->my_sink);
@@ -2136,14 +2138,13 @@ static void free_source_pin(struct gstdemux_source *pin)
if (pin->their_src) { - if (pin->flipfilter) + if (pin->post_sink) { - gst_pad_unlink(pin->their_src, pin->flip_sink); - gst_pad_unlink(pin->flip_src, pin->my_sink); - gst_object_unref(pin->flip_src); - gst_object_unref(pin->flip_sink); - pin->flipfilter = NULL; - pin->flip_src = pin->flip_sink = NULL; + gst_pad_unlink(pin->their_src, pin->post_sink); + gst_pad_unlink(pin->post_src, pin->my_sink); + gst_object_unref(pin->post_src); + gst_object_unref(pin->post_sink); + pin->post_src = pin->post_sink = NULL; } else gst_pad_unlink(pin->their_src, pin->my_sink);
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/gstdemux.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index 8e36644030a..f9eed906b6e 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -1745,6 +1745,24 @@ static HRESULT gstdecoder_source_get_media_type(struct gstdemux_source *pin, * vih->bmiHeader.biHeight * vih->bmiHeader.biBitCount / 8; return S_OK; } + else if (IsEqualGUID(&pin->mt.majortype, &MEDIATYPE_Audio) && index == 1) + { + const WAVEFORMATEX *our_format = (WAVEFORMATEX *)pin->mt.pbFormat; + WAVEFORMATEX *format; + + *mt = pin->mt; + mt->subtype = MEDIASUBTYPE_PCM; + mt->pbFormat = CoTaskMemAlloc(sizeof(WAVEFORMATEX)); + format = (WAVEFORMATEX *)mt->pbFormat; + format->wFormatTag = WAVE_FORMAT_PCM; + format->nChannels = 2; + format->nSamplesPerSec = our_format->nSamplesPerSec; + format->wBitsPerSample = 16; + format->nBlockAlign = 4; + format->nAvgBytesPerSec = format->nSamplesPerSec * 4; + format->cbSize = 0; + return S_OK; + }
return VFW_S_NO_MORE_ITEMS; }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/gst_guids.h | 1 - dlls/winegstreamer/gst_private.h | 1 - dlls/winegstreamer/gsttffilter.c | 120 ------------------------------- dlls/winegstreamer/main.c | 35 --------- 4 files changed, 157 deletions(-)
diff --git a/dlls/winegstreamer/gst_guids.h b/dlls/winegstreamer/gst_guids.h index fe7b65e4454..e50ecb48519 100644 --- a/dlls/winegstreamer/gst_guids.h +++ b/dlls/winegstreamer/gst_guids.h @@ -19,7 +19,6 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
-DEFINE_GUID(CLSID_Gstreamer_AudioConvert, 0x334b2ec9, 0xf2b5, 0x40b9, 0x84, 0x32, 0x4a, 0x00, 0xe0, 0x03, 0x86, 0xa8); DEFINE_GUID(CLSID_Gstreamer_Mp3, 0x728dcf55, 0x128f, 0x4dd1, 0xad, 0x22, 0xbe, 0xcf, 0xa6, 0x6c, 0xe7, 0xaa); DEFINE_GUID(CLSID_Gstreamer_Splitter, 0xf9d8d64e, 0xa144, 0x47dc, 0x8e, 0xe0, 0xf5, 0x34, 0x98, 0x37, 0x2c, 0x29); DEFINE_GUID(WINESUBTYPE_Gstreamer, 0xffffffff, 0x128f, 0x4dd1, 0xad, 0x22, 0xbe, 0xcf, 0xa6, 0x6c, 0xe7, 0xaa); diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 37b19ea6265..7108a32e401 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -37,7 +37,6 @@
IUnknown * CALLBACK avi_splitter_create(IUnknown *outer, HRESULT *phr) DECLSPEC_HIDDEN; IUnknown * CALLBACK mpeg_splitter_create(IUnknown *outer, HRESULT *phr) DECLSPEC_HIDDEN; -IUnknown * CALLBACK Gstreamer_AudioConvert_create(IUnknown *pUnkOuter, HRESULT *phr); IUnknown * CALLBACK Gstreamer_Mp3_create(IUnknown *pUnkOuter, HRESULT *phr); IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *pUnkOuter, HRESULT *phr); IUnknown * CALLBACK wave_parser_create(IUnknown *outer, HRESULT *phr) DECLSPEC_HIDDEN; diff --git a/dlls/winegstreamer/gsttffilter.c b/dlls/winegstreamer/gsttffilter.c index 5d1a98b0f5c..21feefe09d2 100644 --- a/dlls/winegstreamer/gsttffilter.c +++ b/dlls/winegstreamer/gsttffilter.c @@ -626,123 +626,3 @@ IUnknown * CALLBACK Gstreamer_Mp3_create(IUnknown *punkouter, HRESULT *phr)
return obj; } - -static HRESULT WINAPI Gstreamer_AudioConvert_QueryConnect(TransformFilter *iface, const AM_MEDIA_TYPE *amt) -{ - GstTfImpl *This = (GstTfImpl*)iface; - TRACE("%p %p\n", This, amt); - - if (!IsEqualGUID(&amt->majortype, &MEDIATYPE_Audio) || - !IsEqualGUID(&amt->subtype, &MEDIASUBTYPE_PCM) || - !IsEqualGUID(&amt->formattype, &FORMAT_WaveFormatEx)) - return S_FALSE; - return S_OK; -} - -static HRESULT audio_converter_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *amt) -{ - GstTfImpl *This = (GstTfImpl*)tf; - GstCaps *capsin, *capsout; - AM_MEDIA_TYPE *outpmt = &This->tf.pmt; - WAVEFORMATEX *inwfe; - WAVEFORMATEX *outwfe; - WAVEFORMATEXTENSIBLE *outwfx; - GstAudioFormat format; - HRESULT hr; - BOOL inisfloat = FALSE; - int indepth; - - mark_wine_thread(); - - if (Gstreamer_AudioConvert_QueryConnect(&This->tf, amt) == S_FALSE || !amt->pbFormat) - return E_FAIL; - - FreeMediaType(outpmt); - *outpmt = *amt; - outpmt->pUnk = NULL; - outpmt->cbFormat = sizeof(WAVEFORMATEXTENSIBLE); - outpmt->pbFormat = CoTaskMemAlloc(outpmt->cbFormat); - - inwfe = (WAVEFORMATEX*)amt->pbFormat; - indepth = inwfe->wBitsPerSample; - if (inwfe->wFormatTag == WAVE_FORMAT_EXTENSIBLE) { - WAVEFORMATEXTENSIBLE *inwfx = (WAVEFORMATEXTENSIBLE*)inwfe; - inisfloat = IsEqualGUID(&inwfx->SubFormat, &KSDATAFORMAT_SUBTYPE_IEEE_FLOAT); - if (inwfx->Samples.wValidBitsPerSample) - indepth = inwfx->Samples.wValidBitsPerSample; - } else if (inwfe->wFormatTag == WAVE_FORMAT_IEEE_FLOAT) - inisfloat = TRUE; - - if (inisfloat) - format = inwfe->wBitsPerSample == 64 ? GST_AUDIO_FORMAT_F64LE : GST_AUDIO_FORMAT_F32LE; - else - format = gst_audio_format_build_integer(inwfe->wBitsPerSample != 8, G_LITTLE_ENDIAN, - inwfe->wBitsPerSample, indepth); - - capsin = gst_caps_new_simple("audio/x-raw", - "format", G_TYPE_STRING, gst_audio_format_to_string(format), - "channels", G_TYPE_INT, inwfe->nChannels, - "rate", G_TYPE_INT, inwfe->nSamplesPerSec, - NULL); - - outwfe = (WAVEFORMATEX*)outpmt->pbFormat; - outwfx = (WAVEFORMATEXTENSIBLE*)outwfe; - outwfe->wFormatTag = WAVE_FORMAT_EXTENSIBLE; - outwfe->nChannels = 2; - outwfe->nSamplesPerSec = inwfe->nSamplesPerSec; - outwfe->wBitsPerSample = 16; - outwfe->nBlockAlign = outwfe->nChannels * outwfe->wBitsPerSample / 8; - outwfe->nAvgBytesPerSec = outwfe->nBlockAlign * outwfe->nSamplesPerSec; - outwfe->cbSize = sizeof(*outwfx) - sizeof(*outwfe); - outwfx->Samples.wValidBitsPerSample = outwfe->wBitsPerSample; - outwfx->dwChannelMask = SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT; - outwfx->SubFormat = KSDATAFORMAT_SUBTYPE_PCM; - - capsout = gst_caps_new_simple("audio/x-raw", - "format", G_TYPE_STRING, "S16LE", - "channels", G_TYPE_INT, outwfe->nChannels, - "rate", G_TYPE_INT, outwfe->nSamplesPerSec, - NULL); - - - hr = Gstreamer_transform_ConnectInput(This, amt, capsin, capsout); - gst_caps_unref(capsin); - gst_caps_unref(capsout); - - This->cbBuffer = inwfe->nAvgBytesPerSec; - return hr; -} - -static const TransformFilterFuncTable Gstreamer_AudioConvert_vtbl = { - .pfnDecideBufferSize = Gstreamer_transform_DecideBufferSize, - .pfnStartStreaming = Gstreamer_transform_ProcessBegin, - .pfnReceive = Gstreamer_transform_ProcessData, - .pfnStopStreaming = Gstreamer_transform_ProcessEnd, - .pfnCheckInputType = Gstreamer_AudioConvert_QueryConnect, - .transform_connect_sink = audio_converter_connect_sink, - .pfnBreakConnect = Gstreamer_transform_Cleanup, - .pfnEndOfStream = Gstreamer_transform_EndOfStream, - .pfnBeginFlush = Gstreamer_transform_BeginFlush, - .pfnEndFlush = Gstreamer_transform_EndFlush, - .pfnNewSegment = Gstreamer_transform_NewSegment, - .pfnNotify = Gstreamer_transform_QOS, -}; - -IUnknown * CALLBACK Gstreamer_AudioConvert_create(IUnknown *punkouter, HRESULT *phr) -{ - IUnknown *obj = NULL; - - TRACE("%p %p\n", punkouter, phr); - - if (!init_gstreamer()) - { - *phr = E_FAIL; - return NULL; - } - - *phr = Gstreamer_transform_create(punkouter, &CLSID_Gstreamer_AudioConvert, "audioconvert", &Gstreamer_AudioConvert_vtbl, (LPVOID*)&obj); - - TRACE("returning %p\n", obj); - - return obj; -} diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c index cdc3ba0ddce..3e0ef28afb6 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -40,8 +40,6 @@ static const WCHAR wGstreamer_Splitter[] = {'G','S','t','r','e','a','m','e','r',' ','s','p','l','i','t','t','e','r',' ','f','i','l','t','e','r',0}; static const WCHAR wGstreamer_Mp3[] = {'G','S','t','r','e','a','m','e','r',' ','M','p','3',' ','f','i','l','t','e','r',0}; -static const WCHAR wGstreamer_AudioConvert[] = -{'G','S','t','r','e','a','m','e','r',' ','A','u','d','i','o','C','o','n','v','e','r','t',' ','f','i','l','t','e','r',0}; static const WCHAR wave_parserW[] = {'W','a','v','e',' ','P','a','r','s','e','r',0}; static const WCHAR avi_splitterW[] = @@ -122,32 +120,6 @@ AMOVIESETUP_FILTER const amfMp3 = amfMp3Pin };
-AMOVIESETUP_PIN amfAudioConvertPin[] = -{ { wNull, - FALSE, FALSE, FALSE, FALSE, - &GUID_NULL, - NULL, - 1, - amfMTaudio - }, - { - wNull, - FALSE, TRUE, FALSE, FALSE, - &GUID_NULL, - NULL, - 1, - amfMTaudio - }, -}; - -AMOVIESETUP_FILTER const amfAudioConvert = -{ &CLSID_Gstreamer_AudioConvert, - wGstreamer_AudioConvert, - MERIT_UNLIKELY, - 2, - amfAudioConvertPin -}; - static const AMOVIESETUP_MEDIATYPE wave_parser_sink_type_data[] = { {&MEDIATYPE_Stream, &MEDIASUBTYPE_WAVE}, @@ -295,13 +267,6 @@ FactoryTemplate const g_Templates[] = { NULL, &amfMp3, }, - { - wGstreamer_AudioConvert, - &CLSID_Gstreamer_AudioConvert, - Gstreamer_AudioConvert_create, - NULL, - &amfAudioConvert, - }, { wave_parserW, &CLSID_WAVEParser,