Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/tests/avisplit.c | 16 ++++++++-------- dlls/winegstreamer/gstdemux.c | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/dlls/quartz/tests/avisplit.c b/dlls/quartz/tests/avisplit.c index befcac404c9..31cb767b607 100644 --- a/dlls/quartz/tests/avisplit.c +++ b/dlls/quartz/tests/avisplit.c @@ -621,42 +621,42 @@ static void test_media_types(void)
pmt->majortype = GUID_NULL; hr = IPin_QueryAccept(pin, pmt); - todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); pmt->majortype = MEDIATYPE_Video;
pmt->subtype = GUID_NULL; hr = IPin_QueryAccept(pin, pmt); - todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); pmt->subtype = MEDIASUBTYPE_I420;
pmt->formattype = GUID_NULL; hr = IPin_QueryAccept(pin, pmt); - todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); pmt->formattype = FORMAT_None; hr = IPin_QueryAccept(pin, pmt); - todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); pmt->formattype = FORMAT_VideoInfo;
vih = (VIDEOINFOHEADER *)pmt->pbFormat;
vih->AvgTimePerFrame = 10000; hr = IPin_QueryAccept(pin, pmt); - todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); vih->AvgTimePerFrame = 1000 * 10000;
vih->dwBitRate = 1000000; hr = IPin_QueryAccept(pin, pmt); - todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); vih->dwBitRate = 0;
SetRect(&vih->rcSource, 0, 0, 32, 24); hr = IPin_QueryAccept(pin, pmt); - todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); SetRect(&vih->rcSource, 0, 0, 0, 0);
vih->bmiHeader.biCompression = BI_RGB; hr = IPin_QueryAccept(pin, pmt); - todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); vih->bmiHeader.biCompression = mmioFOURCC('I','4','2','0');
CoTaskMemFree(pmt->pbFormat); diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index dadad69beb7..81a0617e56d 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -2377,7 +2377,7 @@ static BOOL avi_splitter_init_gst(struct gstdemux *filter)
static HRESULT avi_splitter_source_query_accept(struct gstdemux_source *pin, const AM_MEDIA_TYPE *mt) { - return S_OK; + return compare_media_types(mt, &pin->mt) ? S_OK : S_FALSE; }
IUnknown * CALLBACK avi_splitter_create(IUnknown *outer, HRESULT *phr)
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/quartz/tests/mpegsplit.c | 18 +++++++++--------- dlls/winegstreamer/gstdemux.c | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/dlls/quartz/tests/mpegsplit.c b/dlls/quartz/tests/mpegsplit.c index 627f4f21efd..c45f982a027 100644 --- a/dlls/quartz/tests/mpegsplit.c +++ b/dlls/quartz/tests/mpegsplit.c @@ -695,41 +695,41 @@ static void test_media_types(void)
pmt->majortype = MEDIATYPE_Video; hr = IPin_QueryAccept(pin, pmt); - todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); pmt->majortype = GUID_NULL; hr = IPin_QueryAccept(pin, pmt); - todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); pmt->majortype = MEDIATYPE_Audio;
pmt->subtype = MEDIASUBTYPE_MPEG1Audio; hr = IPin_QueryAccept(pin, pmt); - todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); pmt->subtype = MEDIASUBTYPE_MPEG1Packet; hr = IPin_QueryAccept(pin, pmt); - todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); pmt->subtype = MEDIASUBTYPE_MPEG1Video; hr = IPin_QueryAccept(pin, pmt); - todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); pmt->subtype = MEDIASUBTYPE_MPEG1AudioPayload;
pmt->formattype = FORMAT_None; hr = IPin_QueryAccept(pin, pmt); - todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); pmt->formattype = GUID_NULL; hr = IPin_QueryAccept(pin, pmt); - todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); pmt->formattype = FORMAT_WaveFormatEx;
wfx = (MPEG1WAVEFORMAT *)pmt->pbFormat;
wfx->fwHeadLayer = ACM_MPEG_LAYER2; hr = IPin_QueryAccept(pin, pmt); - todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); wfx->fwHeadLayer = ACM_MPEG_LAYER3;
wfx->wfx.wFormatTag = WAVE_FORMAT_MPEGLAYER3; hr = IPin_QueryAccept(pin, pmt); - todo_wine ok(hr == S_FALSE, "Got hr %#x.\n", hr); + ok(hr == S_FALSE, "Got hr %#x.\n", hr); wfx->wfx.wFormatTag = WAVE_FORMAT_MPEG;
CoTaskMemFree(pmt->pbFormat); diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index 81a0617e56d..47eb30383b6 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -2500,7 +2500,7 @@ static BOOL mpeg_splitter_init_gst(struct gstdemux *filter)
static HRESULT mpeg_splitter_source_query_accept(struct gstdemux_source *pin, const AM_MEDIA_TYPE *mt) { - return S_OK; + return compare_media_types(mt, &pin->mt) ? S_OK : S_FALSE; }
static HRESULT mpeg_splitter_query_interface(struct strmbase_filter *iface, REFIID iid, void **out)
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/gstdemux.c | 54 +++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 9 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index 47eb30383b6..625d9f31cd4 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -76,6 +76,7 @@ struct gstdemux
BOOL (*init_gst)(struct gstdemux *filter); HRESULT (*source_query_accept)(struct gstdemux_source *pin, const AM_MEDIA_TYPE *mt); + HRESULT (*source_get_media_type)(struct gstdemux_source *pin, unsigned int index, AM_MEDIA_TYPE *mt); };
struct gstdemux_source @@ -1537,6 +1538,15 @@ static HRESULT gstdecoder_source_query_accept(struct gstdemux_source *pin, const return S_OK; }
+static HRESULT gstdecoder_source_get_media_type(struct gstdemux_source *pin, + unsigned int index, AM_MEDIA_TYPE *mt) +{ + if (index > 0) + return VFW_S_NO_MORE_ITEMS; + CopyMediaType(mt, &pin->mt); + return S_OK; +} + IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *outer, HRESULT *phr) { struct gstdemux *object; @@ -1562,6 +1572,7 @@ IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *outer, HRESULT *phr) object->error_event = CreateEventW(NULL, TRUE, FALSE, NULL); object->init_gst = gstdecoder_init_gst; object->source_query_accept = gstdecoder_source_query_accept; + object->source_get_media_type = gstdecoder_source_get_media_type; *phr = S_OK;
TRACE("Created GStreamer demuxer %p.\n", object); @@ -1873,16 +1884,11 @@ static HRESULT source_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TY return filter->source_query_accept(pin, mt); }
-static HRESULT source_get_media_type(struct strmbase_pin *iface, unsigned int iPosition, AM_MEDIA_TYPE *pmt) +static HRESULT source_get_media_type(struct strmbase_pin *iface, unsigned int index, AM_MEDIA_TYPE *mt) { - struct gstdemux_source *This = impl_source_from_IPin(&iface->IPin_iface); - - if (iPosition > 0) - return VFW_S_NO_MORE_ITEMS; - - CopyMediaType(pmt, &This->mt); - - return S_OK; + struct gstdemux_source *pin = impl_source_from_IPin(&iface->IPin_iface); + struct gstdemux *filter = impl_from_strmbase_filter(iface->filter); + return filter->source_get_media_type(pin, index, mt); }
static HRESULT WINAPI GSTOutPin_DecideBufferSize(struct strmbase_source *iface, @@ -2268,6 +2274,15 @@ static HRESULT wave_parser_source_query_accept(struct gstdemux_source *pin, cons return compare_media_types(mt, &pin->mt) ? S_OK : S_FALSE; }
+static HRESULT wave_parser_source_get_media_type(struct gstdemux_source *pin, + unsigned int index, AM_MEDIA_TYPE *mt) +{ + if (index > 0) + return VFW_S_NO_MORE_ITEMS; + CopyMediaType(mt, &pin->mt); + return S_OK; +} + IUnknown * CALLBACK wave_parser_create(IUnknown *outer, HRESULT *phr) { static const WCHAR sink_name[] = {'i','n','p','u','t',' ','p','i','n',0}; @@ -2292,6 +2307,7 @@ IUnknown * CALLBACK wave_parser_create(IUnknown *outer, HRESULT *phr) object->init_gst = wave_parser_init_gst; object->error_event = CreateEventW(NULL, TRUE, FALSE, NULL); object->source_query_accept = wave_parser_source_query_accept; + object->source_get_media_type = wave_parser_source_get_media_type; *phr = S_OK;
TRACE("Created WAVE parser %p.\n", object); @@ -2380,6 +2396,15 @@ static HRESULT avi_splitter_source_query_accept(struct gstdemux_source *pin, con return compare_media_types(mt, &pin->mt) ? S_OK : S_FALSE; }
+static HRESULT avi_splitter_source_get_media_type(struct gstdemux_source *pin, + unsigned int index, AM_MEDIA_TYPE *mt) +{ + if (index > 0) + return VFW_S_NO_MORE_ITEMS; + CopyMediaType(mt, &pin->mt); + return S_OK; +} + IUnknown * CALLBACK avi_splitter_create(IUnknown *outer, HRESULT *phr) { static const WCHAR sink_name[] = {'i','n','p','u','t',' ','p','i','n',0}; @@ -2405,6 +2430,7 @@ IUnknown * CALLBACK avi_splitter_create(IUnknown *outer, HRESULT *phr) object->error_event = CreateEventW(NULL, TRUE, FALSE, NULL); object->init_gst = avi_splitter_init_gst; object->source_query_accept = avi_splitter_source_query_accept; + object->source_get_media_type = avi_splitter_source_get_media_type; *phr = S_OK;
TRACE("Created AVI splitter %p.\n", object); @@ -2503,6 +2529,15 @@ static HRESULT mpeg_splitter_source_query_accept(struct gstdemux_source *pin, co return compare_media_types(mt, &pin->mt) ? S_OK : S_FALSE; }
+static HRESULT mpeg_splitter_source_get_media_type(struct gstdemux_source *pin, + unsigned int index, AM_MEDIA_TYPE *mt) +{ + if (index > 0) + return VFW_S_NO_MORE_ITEMS; + CopyMediaType(mt, &pin->mt); + return S_OK; +} + static HRESULT mpeg_splitter_query_interface(struct strmbase_filter *iface, REFIID iid, void **out) { struct gstdemux *filter = impl_from_strmbase_filter(iface); @@ -2556,6 +2591,7 @@ IUnknown * CALLBACK mpeg_splitter_create(IUnknown *outer, HRESULT *phr) object->error_event = CreateEventW(NULL, TRUE, FALSE, NULL); object->init_gst = mpeg_splitter_init_gst; object->source_query_accept = mpeg_splitter_source_query_accept; + object->source_get_media_type = mpeg_splitter_source_get_media_type; object->enum_sink_first = TRUE; *phr = S_OK;
The idea being firstly that it's more efficient to handle this all within one GStreamer pipeline, especially since we may need to be converting color spaces anyway (for videoflip), and secondly that this renders obsolete the color space converter transform filters in gsttffilter.c.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/gstdemux.c | 238 +++++++++++++++++++++++++++++++--- 1 file changed, 219 insertions(+), 19 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c index 625d9f31cd4..8213bfdb439 100644 --- a/dlls/winegstreamer/gstdemux.c +++ b/dlls/winegstreamer/gstdemux.c @@ -41,6 +41,7 @@ #include "mmreg.h" #include "ks.h" #include "initguid.h" +#include "wmcodecdsp.h" #include "ksmedia.h"
WINE_DEFAULT_DEBUG_CHANNEL(gstreamer); @@ -384,19 +385,96 @@ static gboolean amt_from_gst_caps(const GstCaps *caps, AM_MEDIA_TYPE *mt) } }
-static gboolean accept_caps_sink(GstPad *pad, GstCaps *caps) +static GstCaps *amt_to_gst_caps_video(const AM_MEDIA_TYPE *mt) { - struct gstdemux_source *pin = gst_pad_get_element_private(pad); - gchar *caps_str = gst_caps_to_string(caps); - AM_MEDIA_TYPE mt; - gboolean ret; + static const struct + { + const GUID *subtype; + GstVideoFormat format; + } + format_map[] = + { + {&MEDIASUBTYPE_ARGB32, GST_VIDEO_FORMAT_BGRA}, + {&MEDIASUBTYPE_RGB32, GST_VIDEO_FORMAT_BGRx}, + {&MEDIASUBTYPE_RGB24, GST_VIDEO_FORMAT_BGR}, + {&MEDIASUBTYPE_RGB565, GST_VIDEO_FORMAT_BGR16}, + {&MEDIASUBTYPE_RGB555, GST_VIDEO_FORMAT_BGR15}, + }; + + const VIDEOINFOHEADER *vih = (VIDEOINFOHEADER *)mt->pbFormat; + GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN; + GstVideoInfo info; + unsigned int i; + GstCaps *caps;
- TRACE("pin %p, caps %s.\n", pin, debugstr_a(caps_str)); - g_free(caps_str); + for (i = 0; i < ARRAY_SIZE(format_map); ++i) + { + if (IsEqualGUID(&mt->subtype, format_map[i].subtype)) + { + format = format_map[i].format; + break; + } + } + + if (format == GST_VIDEO_FORMAT_UNKNOWN) + format = gst_video_format_from_fourcc(vih->bmiHeader.biCompression); + + if (format == GST_VIDEO_FORMAT_UNKNOWN) + { + FIXME("Unknown video format (subtype %s, compression %#x).\n", + debugstr_guid(&mt->subtype), vih->bmiHeader.biCompression); + return NULL; + } + + gst_video_info_set_format(&info, format, vih->bmiHeader.biWidth, vih->bmiHeader.biHeight); + if ((caps = gst_video_info_to_caps(&info))) + { + /* Clear the framerate; we don't actually care about it. (Yes, + * VIDEOINFOHEADER has an AvgTimePerFrame field, but that shouldn't + * matter for checking compatible caps.) */ + for (i = 0; i < gst_caps_get_size(caps); ++i) + gst_structure_remove_field(gst_caps_get_structure(caps, i), "framerate"); + } + return caps; +}
- if ((ret = amt_from_gst_caps(caps, &mt))) - FreeMediaType(&mt); - return ret; +static GstCaps *amt_to_gst_caps_audio(const AM_MEDIA_TYPE *mt) +{ + const WAVEFORMATEX *wfx = (WAVEFORMATEX *)mt->pbFormat; + GstAudioFormat format = GST_AUDIO_FORMAT_UNKNOWN; + GstAudioInfo info; + + if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_PCM)) + format = gst_audio_format_build_integer(wfx->wBitsPerSample != 8, + G_LITTLE_ENDIAN, wfx->wBitsPerSample, wfx->wBitsPerSample); + else if (IsEqualGUID(&mt->subtype, &MEDIASUBTYPE_IEEE_FLOAT)) + { + if (wfx->wBitsPerSample == 32) + format = GST_AUDIO_FORMAT_F32LE; + else if (wfx->wBitsPerSample == 64) + format = GST_AUDIO_FORMAT_F64LE; + } + + if (format == GST_AUDIO_FORMAT_UNKNOWN) + { + FIXME("Unknown audio format (subtype %s, depth %u).\n", + debugstr_guid(&mt->subtype), wfx->wBitsPerSample); + return NULL; + } + + gst_audio_info_set_format(&info, format, wfx->nSamplesPerSec, wfx->nChannels, NULL); + return gst_audio_info_to_caps(&info); +} + +static GstCaps *amt_to_gst_caps(const AM_MEDIA_TYPE *mt) +{ + if (IsEqualGUID(&mt->majortype, &MEDIATYPE_Video)) + return amt_to_gst_caps_video(mt); + else if (IsEqualGUID(&mt->majortype, &MEDIATYPE_Audio)) + return amt_to_gst_caps_audio(mt); + + FIXME("Unknown major type %s.\n", debugstr_guid(&mt->majortype)); + return NULL; }
static gboolean setcaps_sink(GstPad *pad, GstCaps *caps) @@ -424,15 +502,90 @@ static gboolean setcaps_sink(GstPad *pad, GstCaps *caps)
static gboolean query_sink(GstPad *pad, GstObject *parent, GstQuery *query) { - switch (GST_QUERY_TYPE (query)) { + struct gstdemux_source *pin = gst_pad_get_element_private(pad); + + TRACE("pin %p, type "%s".\n", pin, gst_query_type_get_name(query->type)); + + switch (query->type) + { + case GST_QUERY_CAPS: + { + GstCaps *caps, *filter, *temp; + + gst_query_parse_caps(query, &filter); + + if (pin->pin.pin.peer) + caps = amt_to_gst_caps(&pin->pin.pin.mt); + else + caps = gst_caps_new_any(); + if (!caps) + return FALSE; + + if (filter) + { + temp = gst_caps_intersect(caps, filter); + gst_caps_unref(caps); + caps = temp; + } + + gst_query_set_caps_result(query, caps); + gst_caps_unref(caps); + return TRUE; + } case GST_QUERY_ACCEPT_CAPS: { + gboolean ret = TRUE; + AM_MEDIA_TYPE mt; GstCaps *caps; - gboolean res; + + if (!pin->pin.pin.peer) + { + gst_query_set_accept_caps_result(query, TRUE); + return TRUE; + } + gst_query_parse_accept_caps(query, &caps); - res = accept_caps_sink(pad, caps); - gst_query_set_accept_caps_result(query, res); - return TRUE; /* FIXME */ + 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); + + 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; } default: return gst_pad_query_default (pad, parent, query); @@ -1535,16 +1688,63 @@ static BOOL gstdecoder_init_gst(struct gstdemux *filter)
static HRESULT gstdecoder_source_query_accept(struct gstdemux_source *pin, const AM_MEDIA_TYPE *mt) { + /* At least make sure we can convert it to GstCaps. */ + GstCaps *caps = amt_to_gst_caps(mt); + + if (!caps) + return S_FALSE; + gst_caps_unref(caps); return S_OK; }
static HRESULT gstdecoder_source_get_media_type(struct gstdemux_source *pin, unsigned int index, AM_MEDIA_TYPE *mt) { - if (index > 0) - return VFW_S_NO_MORE_ITEMS; - CopyMediaType(mt, &pin->mt); - return S_OK; + static const struct + { + const GUID *subtype; + WORD bpp; + DWORD compression; + } + video_types[] = + { + /* Roughly ordered by preference from videoflip. */ + {&MEDIASUBTYPE_AYUV, 32, mmioFOURCC('A','Y','U','V')}, + {&MEDIASUBTYPE_ARGB32, 32, BI_RGB}, + {&MEDIASUBTYPE_RGB32, 32, BI_RGB}, + {&MEDIASUBTYPE_RGB24, 24, BI_RGB}, + {&MEDIASUBTYPE_I420, 12, mmioFOURCC('I','4','2','0')}, + {&MEDIASUBTYPE_YV12, 12, mmioFOURCC('Y','V','1','2')}, + {&MEDIASUBTYPE_IYUV, 12, mmioFOURCC('I','Y','U','V')}, + {&MEDIASUBTYPE_YUY2, 16, mmioFOURCC('Y','U','Y','2')}, + {&MEDIASUBTYPE_UYVY, 16, mmioFOURCC('U','Y','V','Y')}, + {&MEDIASUBTYPE_YVYU, 16, mmioFOURCC('Y','V','Y','U')}, + {&MEDIASUBTYPE_NV12, 12, mmioFOURCC('N','V','1','2')}, + }; + + if (!index) + { + CopyMediaType(mt, &pin->mt); + return S_OK; + } + else if (IsEqualGUID(&pin->mt.majortype, &MEDIATYPE_Video) + && index - 1 < ARRAY_SIZE(video_types)) + { + VIDEOINFOHEADER *vih; + + *mt = pin->mt; + mt->subtype = *video_types[index - 1].subtype; + mt->pbFormat = CoTaskMemAlloc(pin->mt.cbFormat); + memcpy(mt->pbFormat, pin->mt.pbFormat, pin->mt.cbFormat); + vih = (VIDEOINFOHEADER *)mt->pbFormat; + vih->bmiHeader.biBitCount = video_types[index - 1].bpp; + vih->bmiHeader.biCompression = video_types[index - 1].compression; + vih->bmiHeader.biSizeImage = vih->bmiHeader.biWidth + * vih->bmiHeader.biHeight * vih->bmiHeader.biBitCount / 8; + return S_OK; + } + + return VFW_S_NO_MORE_ITEMS; }
IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *outer, HRESULT *phr)
This is handled by the splitter filter now.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/winegstreamer/gst_guids.h | 2 - dlls/winegstreamer/gst_private.h | 2 - dlls/winegstreamer/gsttffilter.c | 217 ------------------------------- dlls/winegstreamer/main.c | 52 -------- 4 files changed, 273 deletions(-)
diff --git a/dlls/winegstreamer/gst_guids.h b/dlls/winegstreamer/gst_guids.h index b445dc59625..fe7b65e4454 100644 --- a/dlls/winegstreamer/gst_guids.h +++ b/dlls/winegstreamer/gst_guids.h @@ -23,5 +23,3 @@ DEFINE_GUID(CLSID_Gstreamer_AudioConvert, 0x334b2ec9, 0xf2b5, 0x40b9, 0x84, 0x32 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); -DEFINE_GUID(CLSID_Gstreamer_YUV2RGB, 0x2d5507df, 0x5ac9, 0x4bb9, 0x9c, 0x09, 0xb2, 0x80, 0xfc, 0x0b, 0xce, 0x01); -DEFINE_GUID(CLSID_Gstreamer_YUV2ARGB, 0x2d5507df, 0x5ac9, 0x4bb9, 0x9c, 0x09, 0xb2, 0x80, 0xfc, 0x0b, 0xce, 0x02); diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h index 122e4c1037e..37b19ea6265 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -39,8 +39,6 @@ IUnknown * CALLBACK avi_splitter_create(IUnknown *outer, HRESULT *phr) DECLSPEC_ 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_YUV2RGB_create(IUnknown *pUnkOuter, HRESULT *phr); -IUnknown * CALLBACK Gstreamer_YUV2ARGB_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 d44a6ae33a6..5d1a98b0f5c 100644 --- a/dlls/winegstreamer/gsttffilter.c +++ b/dlls/winegstreamer/gsttffilter.c @@ -627,223 +627,6 @@ IUnknown * CALLBACK Gstreamer_Mp3_create(IUnknown *punkouter, HRESULT *phr) return obj; }
-static HRESULT WINAPI Gstreamer_YUV_QueryConnect(TransformFilter *iface, const AM_MEDIA_TYPE *amt) -{ - GstTfImpl *This = (GstTfImpl*)iface; - TRACE("%p %p\n", This, amt); - - if (!IsEqualGUID(&amt->majortype, &MEDIATYPE_Video) || - (!IsEqualGUID(&amt->formattype, &FORMAT_VideoInfo) && - !IsEqualGUID(&amt->formattype, &FORMAT_VideoInfo2))) - return S_FALSE; - if (memcmp(&amt->subtype.Data2, &MEDIATYPE_Video.Data2, sizeof(GUID) - sizeof(amt->subtype.Data1))) - return S_FALSE; - switch (amt->subtype.Data1) { - case mmioFOURCC('I','4','2','0'): - case mmioFOURCC('Y','V','1','2'): - case mmioFOURCC('N','V','1','2'): - case mmioFOURCC('N','V','2','1'): - case mmioFOURCC('Y','U','Y','2'): - case mmioFOURCC('Y','V','Y','U'): - return S_OK; - default: - WARN("Unhandled fourcc %s\n", debugstr_an((char*)&amt->subtype.Data1, 4)); - return S_FALSE; - } -} - -static HRESULT yuv_to_rgb_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *amt) -{ - GstTfImpl *This = (GstTfImpl*)tf; - GstCaps *capsin, *capsout; - AM_MEDIA_TYPE *outpmt = &This->tf.pmt; - HRESULT hr; - int avgtime; - LONG width, height; - - mark_wine_thread(); - - if (Gstreamer_YUV_QueryConnect(&This->tf, amt) == S_FALSE || !amt->pbFormat) - return E_FAIL; - - FreeMediaType(outpmt); - CopyMediaType(outpmt, amt); - - if (IsEqualGUID(&amt->formattype, &FORMAT_VideoInfo)) { - VIDEOINFOHEADER *vih = (VIDEOINFOHEADER*)outpmt->pbFormat; - avgtime = vih->AvgTimePerFrame; - width = vih->bmiHeader.biWidth; - height = vih->bmiHeader.biHeight; - vih->bmiHeader.biBitCount = 24; - vih->bmiHeader.biCompression = BI_RGB; - vih->bmiHeader.biSizeImage = width * abs(height) * 3; - } else { - VIDEOINFOHEADER2 *vih = (VIDEOINFOHEADER2*)outpmt->pbFormat; - avgtime = vih->AvgTimePerFrame; - width = vih->bmiHeader.biWidth; - height = vih->bmiHeader.biHeight; - vih->bmiHeader.biBitCount = 24; - vih->bmiHeader.biCompression = BI_RGB; - vih->bmiHeader.biSizeImage = width * abs(height) * 3; - } - if (!avgtime) - avgtime = 10000000 / 30; - - outpmt->subtype = MEDIASUBTYPE_RGB24; - - capsin = gst_caps_new_simple("video/x-raw", - "format", G_TYPE_STRING, - gst_video_format_to_string( - gst_video_format_from_fourcc(amt->subtype.Data1)), - "width", G_TYPE_INT, width, - "height", G_TYPE_INT, height, - "framerate", GST_TYPE_FRACTION, 10000000, avgtime, - NULL); - capsout = gst_caps_new_simple("video/x-raw", - "format", G_TYPE_STRING, "BGR", - "width", G_TYPE_INT, width, - "height", G_TYPE_INT, height, - "framerate", GST_TYPE_FRACTION, 10000000, avgtime, - NULL); - - hr = Gstreamer_transform_ConnectInput(This, amt, capsin, capsout); - gst_caps_unref(capsin); - gst_caps_unref(capsout); - - This->cbBuffer = width * height * 4; - return hr; -} - -static const TransformFilterFuncTable Gstreamer_YUV2RGB_vtbl = { - .pfnDecideBufferSize = Gstreamer_transform_DecideBufferSize, - .pfnStartStreaming = Gstreamer_transform_ProcessBegin, - .pfnReceive = Gstreamer_transform_ProcessData, - .pfnStopStreaming = Gstreamer_transform_ProcessEnd, - .pfnCheckInputType = Gstreamer_YUV_QueryConnect, - .transform_connect_sink = yuv_to_rgb_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_YUV2RGB_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_YUV2RGB, "videoconvert", &Gstreamer_YUV2RGB_vtbl, (LPVOID*)&obj); - - TRACE("returning %p\n", obj); - - return obj; -} - -static HRESULT yuv_to_argb_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *amt) -{ - GstTfImpl *This = (GstTfImpl*)tf; - GstCaps *capsin, *capsout; - AM_MEDIA_TYPE *outpmt = &This->tf.pmt; - HRESULT hr; - int avgtime; - LONG width, height; - - mark_wine_thread(); - - if (Gstreamer_YUV_QueryConnect(&This->tf, amt) == S_FALSE || !amt->pbFormat) - return E_FAIL; - - FreeMediaType(outpmt); - CopyMediaType(outpmt, amt); - - if (IsEqualGUID(&amt->formattype, &FORMAT_VideoInfo)) { - VIDEOINFOHEADER *vih = (VIDEOINFOHEADER*)outpmt->pbFormat; - avgtime = vih->AvgTimePerFrame; - width = vih->bmiHeader.biWidth; - height = vih->bmiHeader.biHeight; - vih->bmiHeader.biBitCount = 32; - vih->bmiHeader.biCompression = BI_RGB; - vih->bmiHeader.biSizeImage = width * abs(height) * 3; - } else { - VIDEOINFOHEADER2 *vih = (VIDEOINFOHEADER2*)outpmt->pbFormat; - avgtime = vih->AvgTimePerFrame; - width = vih->bmiHeader.biWidth; - height = vih->bmiHeader.biHeight; - vih->bmiHeader.biBitCount = 32; - vih->bmiHeader.biCompression = BI_RGB; - vih->bmiHeader.biSizeImage = width * abs(height) * 3; - } - if (!avgtime) - avgtime = 10000000 / 30; - - outpmt->subtype = MEDIASUBTYPE_ARGB32; - - capsin = gst_caps_new_simple("video/x-raw", - "format", G_TYPE_STRING, - gst_video_format_to_string( - gst_video_format_from_fourcc(amt->subtype.Data1)), - "width", G_TYPE_INT, width, - "height", G_TYPE_INT, height, - "framerate", GST_TYPE_FRACTION, 10000000, avgtime, - NULL); - capsout = gst_caps_new_simple("video/x-raw", - "format", G_TYPE_STRING, "BGRA", - "width", G_TYPE_INT, width, - "height", G_TYPE_INT, height, - "framerate", GST_TYPE_FRACTION, 10000000, avgtime, - NULL); - - hr = Gstreamer_transform_ConnectInput(This, amt, capsin, capsout); - gst_caps_unref(capsin); - gst_caps_unref(capsout); - - This->cbBuffer = width * height * 4; - return hr; -} - -static const TransformFilterFuncTable Gstreamer_YUV2ARGB_vtbl = { - .pfnDecideBufferSize = Gstreamer_transform_DecideBufferSize, - .pfnStartStreaming = Gstreamer_transform_ProcessBegin, - .pfnReceive = Gstreamer_transform_ProcessData, - .pfnStopStreaming = Gstreamer_transform_ProcessEnd, - .pfnCheckInputType = Gstreamer_YUV_QueryConnect, - .transform_connect_sink = yuv_to_argb_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_YUV2ARGB_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_YUV2ARGB, "videoconvert", &Gstreamer_YUV2ARGB_vtbl, (LPVOID*)&obj); - - TRACE("returning %p\n", obj); - - return obj; -} - static HRESULT WINAPI Gstreamer_AudioConvert_QueryConnect(TransformFilter *iface, const AM_MEDIA_TYPE *amt) { GstTfImpl *This = (GstTfImpl*)iface; diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c index 379f54ab4ec..cdc3ba0ddce 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c @@ -38,10 +38,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(gstreamer);
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_YUV2RGB[] = -{'G','S','t','r','e','a','m','e','r',' ','Y','U','V',' ','t','o',' ','R','G','B',' ','f','i','l','t','e','r',0}; -static const WCHAR wGstreamer_YUV2ARGB[] = -{'G','S','t','r','e','a','m','e','r',' ','Y','U','V',' ','t','o',' ','A','R','G','B',' ','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[] = @@ -100,40 +96,6 @@ static const AMOVIESETUP_FILTER amfSplitter = amfSplitPin };
-static const AMOVIESETUP_PIN amfYUVPin[] = -{ { wNull, - FALSE, FALSE, FALSE, FALSE, - &GUID_NULL, - NULL, - 1, - amfMTvideo - }, - { - wNull, - FALSE, TRUE, FALSE, FALSE, - &GUID_NULL, - NULL, - 1, - amfMTvideo - }, -}; - -static const AMOVIESETUP_FILTER amfYUV2RGB = -{ &CLSID_Gstreamer_YUV2RGB, - wGstreamer_YUV2RGB, - MERIT_UNLIKELY, - 2, - amfYUVPin -}; - -static const AMOVIESETUP_FILTER amfYUV2ARGB = -{ &CLSID_Gstreamer_YUV2ARGB, - wGstreamer_YUV2ARGB, - MERIT_UNLIKELY, - 2, - amfYUVPin -}; - AMOVIESETUP_PIN amfMp3Pin[] = { { wNull, FALSE, FALSE, FALSE, FALSE, @@ -326,20 +288,6 @@ FactoryTemplate const g_Templates[] = { NULL, &amfSplitter, }, - { - wGstreamer_YUV2RGB, - &CLSID_Gstreamer_YUV2RGB, - Gstreamer_YUV2RGB_create, - NULL, - &amfYUV2RGB, - }, - { - wGstreamer_YUV2ARGB, - &CLSID_Gstreamer_YUV2ARGB, - Gstreamer_YUV2ARGB_create, - NULL, - &amfYUV2ARGB, - }, { wGstreamer_Mp3, &CLSID_Gstreamer_Mp3,