winegstreamer: Don't store DirectShow caps.
Primarily so that we can connect using video caps that can't be translated into DirectShow caps. They will later be converted into translatable caps once the DirectShow source pin is connected. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47642 Signed-off-by: Zebediah Figura <z.figura12@gmail.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
3533605293
commit
7be64a8d3e
|
@ -78,7 +78,6 @@ struct gstdemux_source
|
|||
|
||||
GstPad *their_src, *post_sink, *post_src, *my_sink;
|
||||
GstElement *flip;
|
||||
AM_MEDIA_TYPE mt;
|
||||
HANDLE caps_event, eos_event;
|
||||
GstSegment *segment;
|
||||
SourceSeeking seek;
|
||||
|
@ -99,15 +98,11 @@ static HRESULT WINAPI GST_ChangeCurrent(IMediaSeeking *iface);
|
|||
static HRESULT WINAPI GST_ChangeStop(IMediaSeeking *iface);
|
||||
static HRESULT WINAPI GST_ChangeRate(IMediaSeeking *iface);
|
||||
|
||||
static gboolean amt_from_gst_caps_audio_raw(const GstCaps *caps, AM_MEDIA_TYPE *amt)
|
||||
static gboolean amt_from_gst_audio_info(const GstAudioInfo *info, AM_MEDIA_TYPE *amt)
|
||||
{
|
||||
WAVEFORMATEXTENSIBLE *wfe;
|
||||
WAVEFORMATEX *wfx;
|
||||
gint32 depth, bpp;
|
||||
GstAudioInfo ainfo;
|
||||
|
||||
if (!gst_audio_info_from_caps (&ainfo, caps))
|
||||
return FALSE;
|
||||
|
||||
wfe = CoTaskMemAlloc(sizeof(*wfe));
|
||||
wfx = (WAVEFORMATEX*)wfe;
|
||||
|
@ -122,10 +117,10 @@ static gboolean amt_from_gst_caps_audio_raw(const GstCaps *caps, AM_MEDIA_TYPE *
|
|||
|
||||
wfx->wFormatTag = WAVE_FORMAT_EXTENSIBLE;
|
||||
|
||||
wfx->nChannels = ainfo.channels;
|
||||
wfx->nSamplesPerSec = ainfo.rate;
|
||||
depth = GST_AUDIO_INFO_WIDTH(&ainfo);
|
||||
bpp = GST_AUDIO_INFO_DEPTH(&ainfo);
|
||||
wfx->nChannels = info->channels;
|
||||
wfx->nSamplesPerSec = info->rate;
|
||||
depth = GST_AUDIO_INFO_WIDTH(info);
|
||||
bpp = GST_AUDIO_INFO_DEPTH(info);
|
||||
|
||||
if (!depth || depth > 32 || depth % 8)
|
||||
depth = bpp;
|
||||
|
@ -144,7 +139,8 @@ static gboolean amt_from_gst_caps_audio_raw(const GstCaps *caps, AM_MEDIA_TYPE *
|
|||
default:
|
||||
wfe->dwChannelMask = 0;
|
||||
}
|
||||
if (GST_AUDIO_INFO_IS_FLOAT(&ainfo)) {
|
||||
if (GST_AUDIO_INFO_IS_FLOAT(info))
|
||||
{
|
||||
amt->subtype = MEDIASUBTYPE_IEEE_FLOAT;
|
||||
wfe->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
|
||||
} else {
|
||||
|
@ -207,7 +203,7 @@ static gboolean amt_from_gst_video_info(const GstVideoInfo *info, AM_MEDIA_TYPE
|
|||
bih->biBitCount = 16;
|
||||
break;
|
||||
default:
|
||||
FIXME("Unhandled type %s.\n", GST_VIDEO_INFO_NAME(info));
|
||||
WARN("Cannot convert %s to a DirectShow type.\n", GST_VIDEO_INFO_NAME(info));
|
||||
CoTaskMemFree(vih);
|
||||
return FALSE;
|
||||
}
|
||||
|
@ -314,8 +310,16 @@ static gboolean amt_from_gst_caps(const GstCaps *caps, AM_MEDIA_TYPE *mt)
|
|||
const char *type = gst_structure_get_name(gst_caps_get_structure(caps, 0));
|
||||
GstStructure *structure = gst_caps_get_structure(caps, 0);
|
||||
|
||||
memset(mt, 0, sizeof(AM_MEDIA_TYPE));
|
||||
|
||||
if (!strcmp(type, "audio/x-raw"))
|
||||
return amt_from_gst_caps_audio_raw(caps, mt);
|
||||
{
|
||||
GstAudioInfo info;
|
||||
|
||||
if (!(gst_audio_info_from_caps(&info, caps)))
|
||||
return FALSE;
|
||||
return amt_from_gst_audio_info(&info, mt);
|
||||
}
|
||||
else if (!strcmp(type, "video/x-raw"))
|
||||
{
|
||||
GstVideoInfo info;
|
||||
|
@ -331,7 +335,6 @@ static gboolean amt_from_gst_caps(const GstCaps *caps, AM_MEDIA_TYPE *mt)
|
|||
VIDEOINFOHEADER *vih;
|
||||
gint i;
|
||||
|
||||
memset(mt, 0, sizeof(AM_MEDIA_TYPE));
|
||||
mt->majortype = MEDIATYPE_Video;
|
||||
mt->subtype = MEDIASUBTYPE_CVID;
|
||||
mt->bTemporalCompression = TRUE;
|
||||
|
@ -466,24 +469,6 @@ static GstCaps *amt_to_gst_caps(const AM_MEDIA_TYPE *mt)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static gboolean setcaps_sink(GstPad *pad, GstCaps *caps)
|
||||
{
|
||||
struct gstdemux_source *pin = gst_pad_get_element_private(pad);
|
||||
struct gstdemux *filter = impl_from_strmbase_filter(pin->pin.pin.filter);
|
||||
gchar *caps_str = gst_caps_to_string(caps);
|
||||
|
||||
TRACE("filter %p, caps %s.\n", filter, debugstr_a(caps_str));
|
||||
g_free(caps_str);
|
||||
|
||||
FreeMediaType(&pin->mt);
|
||||
|
||||
if (!amt_from_gst_caps(caps, &pin->mt))
|
||||
return FALSE;
|
||||
|
||||
SetEvent(pin->caps_event);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean query_sink(GstPad *pad, GstObject *parent, GstQuery *query)
|
||||
{
|
||||
struct gstdemux_source *pin = gst_pad_get_element_private(pad);
|
||||
|
@ -662,6 +647,7 @@ static gboolean event_src(GstPad *pad, GstObject *parent, GstEvent *event)
|
|||
static gboolean event_sink(GstPad *pad, GstObject *parent, GstEvent *event)
|
||||
{
|
||||
struct gstdemux_source *pin = gst_pad_get_element_private(pad);
|
||||
gboolean ret;
|
||||
|
||||
TRACE("pin %p, type \"%s\".\n", pin, GST_EVENT_TYPE_NAME(event));
|
||||
|
||||
|
@ -722,11 +708,10 @@ static gboolean event_sink(GstPad *pad, GstObject *parent, GstEvent *event)
|
|||
if (pin->pin.pin.peer)
|
||||
IPin_EndFlush(pin->pin.pin.peer);
|
||||
return TRUE;
|
||||
case GST_EVENT_CAPS: {
|
||||
GstCaps *caps;
|
||||
gst_event_parse_caps(event, &caps);
|
||||
return setcaps_sink(pad, caps);
|
||||
}
|
||||
case GST_EVENT_CAPS:
|
||||
ret = gst_pad_event_default(pad, parent, event);
|
||||
SetEvent(pin->caps_event);
|
||||
return ret;
|
||||
default:
|
||||
WARN("Ignoring \"%s\" event.\n", GST_EVENT_TYPE_NAME(event));
|
||||
return gst_pad_event_default(pad, parent, event);
|
||||
|
@ -1678,6 +1663,10 @@ static HRESULT gstdecoder_source_query_accept(struct gstdemux_source *pin, const
|
|||
static HRESULT gstdecoder_source_get_media_type(struct gstdemux_source *pin,
|
||||
unsigned int index, AM_MEDIA_TYPE *mt)
|
||||
{
|
||||
GstCaps *caps = gst_pad_get_current_caps(pin->my_sink);
|
||||
const GstStructure *structure;
|
||||
const char *type;
|
||||
|
||||
static const GstVideoFormat video_formats[] =
|
||||
{
|
||||
/* Try to prefer YUV formats over RGB ones. Most decoders output in the
|
||||
|
@ -1695,42 +1684,48 @@ static HRESULT gstdecoder_source_get_media_type(struct gstdemux_source *pin,
|
|||
GST_VIDEO_FORMAT_BGR,
|
||||
};
|
||||
|
||||
if (!index)
|
||||
assert(caps); /* We shouldn't be able to get here if caps haven't been set. */
|
||||
structure = gst_caps_get_structure(caps, 0);
|
||||
type = gst_structure_get_name(structure);
|
||||
|
||||
memset(mt, 0, sizeof(AM_MEDIA_TYPE));
|
||||
|
||||
if (amt_from_gst_caps(caps, mt))
|
||||
{
|
||||
CopyMediaType(mt, &pin->mt);
|
||||
return S_OK;
|
||||
if (!index--)
|
||||
{
|
||||
gst_caps_unref(caps);
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
else if (IsEqualGUID(&pin->mt.majortype, &MEDIATYPE_Video)
|
||||
&& index - 1 < ARRAY_SIZE(video_formats))
|
||||
|
||||
if (!strcmp(type, "video/x-raw") && index < ARRAY_SIZE(video_formats))
|
||||
{
|
||||
const VIDEOINFOHEADER *vih = (VIDEOINFOHEADER *)pin->mt.pbFormat;
|
||||
gint width, height;
|
||||
GstVideoInfo info;
|
||||
|
||||
gst_video_info_set_format(&info, video_formats[index - 1],
|
||||
vih->bmiHeader.biWidth, vih->bmiHeader.biHeight);
|
||||
gst_caps_unref(caps);
|
||||
gst_structure_get_int(structure, "width", &width);
|
||||
gst_structure_get_int(structure, "height", &height);
|
||||
gst_video_info_set_format(&info, video_formats[index], width, height);
|
||||
if (!amt_from_gst_video_info(&info, mt))
|
||||
return E_OUTOFMEMORY;
|
||||
return S_OK;
|
||||
}
|
||||
else if (IsEqualGUID(&pin->mt.majortype, &MEDIATYPE_Audio) && index == 1)
|
||||
else if (!strcmp(type, "audio/x-raw") && !index)
|
||||
{
|
||||
const WAVEFORMATEX *our_format = (WAVEFORMATEX *)pin->mt.pbFormat;
|
||||
WAVEFORMATEX *format;
|
||||
GstAudioInfo info;
|
||||
gint rate;
|
||||
|
||||
*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;
|
||||
gst_caps_unref(caps);
|
||||
gst_structure_get_int(structure, "rate", &rate);
|
||||
gst_audio_info_set_format(&info, GST_AUDIO_FORMAT_S16LE, rate, 2, NULL);
|
||||
if (!amt_from_gst_audio_info(&info, mt))
|
||||
return E_OUTOFMEMORY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
gst_caps_unref(caps);
|
||||
return VFW_S_NO_MORE_ITEMS;
|
||||
}
|
||||
|
||||
|
@ -2137,7 +2132,6 @@ static void free_source_pin(struct gstdemux_source *pin)
|
|||
gst_object_unref(pin->my_sink);
|
||||
CloseHandle(pin->caps_event);
|
||||
CloseHandle(pin->eos_event);
|
||||
FreeMediaType(&pin->mt);
|
||||
gst_segment_free(pin->segment);
|
||||
|
||||
strmbase_seeking_cleanup(&pin->seek);
|
||||
|
@ -2394,9 +2388,24 @@ static BOOL wave_parser_init_gst(struct gstdemux *filter)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean get_source_amt(const struct gstdemux_source *pin, AM_MEDIA_TYPE *mt)
|
||||
{
|
||||
GstCaps *caps = gst_pad_get_current_caps(pin->my_sink);
|
||||
gboolean ret = amt_from_gst_caps(caps, mt);
|
||||
gst_caps_unref(caps);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HRESULT wave_parser_source_query_accept(struct gstdemux_source *pin, const AM_MEDIA_TYPE *mt)
|
||||
{
|
||||
return compare_media_types(mt, &pin->mt) ? S_OK : S_FALSE;
|
||||
AM_MEDIA_TYPE pad_mt;
|
||||
HRESULT hr;
|
||||
|
||||
if (!get_source_amt(pin, &pad_mt))
|
||||
return E_OUTOFMEMORY;
|
||||
hr = compare_media_types(mt, &pad_mt) ? S_OK : S_FALSE;
|
||||
FreeMediaType(&pad_mt);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT wave_parser_source_get_media_type(struct gstdemux_source *pin,
|
||||
|
@ -2404,7 +2413,8 @@ static HRESULT wave_parser_source_get_media_type(struct gstdemux_source *pin,
|
|||
{
|
||||
if (index > 0)
|
||||
return VFW_S_NO_MORE_ITEMS;
|
||||
CopyMediaType(mt, &pin->mt);
|
||||
if (!get_source_amt(pin, mt))
|
||||
return E_OUTOFMEMORY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -2507,7 +2517,14 @@ 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 compare_media_types(mt, &pin->mt) ? S_OK : S_FALSE;
|
||||
AM_MEDIA_TYPE pad_mt;
|
||||
HRESULT hr;
|
||||
|
||||
if (!get_source_amt(pin, &pad_mt))
|
||||
return E_OUTOFMEMORY;
|
||||
hr = compare_media_types(mt, &pad_mt) ? S_OK : S_FALSE;
|
||||
FreeMediaType(&pad_mt);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT avi_splitter_source_get_media_type(struct gstdemux_source *pin,
|
||||
|
@ -2515,7 +2532,8 @@ static HRESULT avi_splitter_source_get_media_type(struct gstdemux_source *pin,
|
|||
{
|
||||
if (index > 0)
|
||||
return VFW_S_NO_MORE_ITEMS;
|
||||
CopyMediaType(mt, &pin->mt);
|
||||
if (!get_source_amt(pin, mt))
|
||||
return E_OUTOFMEMORY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
@ -2632,7 +2650,14 @@ 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 compare_media_types(mt, &pin->mt) ? S_OK : S_FALSE;
|
||||
AM_MEDIA_TYPE pad_mt;
|
||||
HRESULT hr;
|
||||
|
||||
if (!get_source_amt(pin, &pad_mt))
|
||||
return E_OUTOFMEMORY;
|
||||
hr = compare_media_types(mt, &pad_mt) ? S_OK : S_FALSE;
|
||||
FreeMediaType(&pad_mt);
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT mpeg_splitter_source_get_media_type(struct gstdemux_source *pin,
|
||||
|
@ -2640,7 +2665,8 @@ static HRESULT mpeg_splitter_source_get_media_type(struct gstdemux_source *pin,
|
|||
{
|
||||
if (index > 0)
|
||||
return VFW_S_NO_MORE_ITEMS;
|
||||
CopyMediaType(mt, &pin->mt);
|
||||
if (!get_source_amt(pin, mt))
|
||||
return E_OUTOFMEMORY;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue