[PATCH 4/4] winegstreamer: Store the preferred stream format a wg_format structure.
Zebediah Figura
z.figura12 at gmail.com
Mon Feb 8 15:07:01 CST 2021
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
dlls/winegstreamer/gstdemux.c | 229 +++++-----------------------------
1 file changed, 32 insertions(+), 197 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c
index 73458d9210e..82801900a15 100644
--- a/dlls/winegstreamer/gstdemux.c
+++ b/dlls/winegstreamer/gstdemux.c
@@ -104,12 +104,12 @@ struct wg_parser_stream
{
GstPad *their_src, *post_sink, *post_src, *my_sink;
GstElement *flip;
- GstCaps *caps;
+ struct wg_format preferred_format;
pthread_cond_t event_cond, event_empty_cond;
struct wg_parser_event event;
- bool flushing, eos, enabled;
+ bool flushing, eos, enabled, has_caps;
uint64_t duration;
};
@@ -172,152 +172,6 @@ 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_audio_info(const GstAudioInfo *info, AM_MEDIA_TYPE *amt)
-{
- WAVEFORMATEXTENSIBLE *wfe;
- WAVEFORMATEX *wfx;
- gint32 depth, bpp;
-
- wfe = CoTaskMemAlloc(sizeof(*wfe));
- wfx = (WAVEFORMATEX*)wfe;
- amt->majortype = MEDIATYPE_Audio;
- amt->subtype = MEDIASUBTYPE_PCM;
- amt->formattype = FORMAT_WaveFormatEx;
- amt->pbFormat = (BYTE*)wfe;
- amt->cbFormat = sizeof(*wfe);
- amt->bFixedSizeSamples = TRUE;
- amt->bTemporalCompression = FALSE;
- amt->pUnk = NULL;
-
- wfx->wFormatTag = WAVE_FORMAT_EXTENSIBLE;
-
- 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;
- else if (!bpp)
- bpp = depth;
- wfe->Samples.wValidBitsPerSample = depth;
- wfx->wBitsPerSample = bpp;
- wfx->cbSize = sizeof(*wfe)-sizeof(*wfx);
- switch (wfx->nChannels) {
- case 1: wfe->dwChannelMask = KSAUDIO_SPEAKER_MONO; break;
- case 2: wfe->dwChannelMask = KSAUDIO_SPEAKER_STEREO; break;
- case 4: wfe->dwChannelMask = KSAUDIO_SPEAKER_SURROUND; break;
- case 5: wfe->dwChannelMask = (KSAUDIO_SPEAKER_5POINT1 & ~SPEAKER_LOW_FREQUENCY); break;
- case 6: wfe->dwChannelMask = KSAUDIO_SPEAKER_5POINT1; break;
- case 8: wfe->dwChannelMask = KSAUDIO_SPEAKER_7POINT1; break;
- default:
- wfe->dwChannelMask = 0;
- }
- if (GST_AUDIO_INFO_IS_FLOAT(info))
- {
- amt->subtype = MEDIASUBTYPE_IEEE_FLOAT;
- wfe->SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
- } else {
- wfe->SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
- if (wfx->nChannels <= 2 && bpp <= 16 && depth == bpp) {
- wfx->wFormatTag = WAVE_FORMAT_PCM;
- wfx->cbSize = 0;
- amt->cbFormat = sizeof(WAVEFORMATEX);
- }
- }
- amt->lSampleSize = wfx->nBlockAlign = wfx->nChannels * wfx->wBitsPerSample/8;
- wfx->nAvgBytesPerSec = wfx->nSamplesPerSec * wfx->nBlockAlign;
- return TRUE;
-}
-
-static gboolean amt_from_gst_video_info(const GstVideoInfo *info, AM_MEDIA_TYPE *amt)
-{
- VIDEOINFO *vih;
- BITMAPINFOHEADER *bih;
- gint32 width, height;
-
- width = GST_VIDEO_INFO_WIDTH(info);
- height = GST_VIDEO_INFO_HEIGHT(info);
-
- vih = CoTaskMemAlloc(sizeof(*vih));
- bih = &vih->bmiHeader;
-
- amt->formattype = FORMAT_VideoInfo;
- amt->pbFormat = (BYTE*)vih;
- amt->cbFormat = sizeof(VIDEOINFOHEADER);
- amt->bFixedSizeSamples = FALSE;
- amt->bTemporalCompression = TRUE;
- amt->lSampleSize = 1;
- amt->pUnk = NULL;
- ZeroMemory(vih, sizeof(*vih));
- amt->majortype = MEDIATYPE_Video;
-
- if (GST_VIDEO_INFO_IS_RGB(info))
- {
- bih->biCompression = BI_RGB;
- switch (GST_VIDEO_INFO_FORMAT(info))
- {
- case GST_VIDEO_FORMAT_BGRA:
- amt->subtype = MEDIASUBTYPE_ARGB32;
- bih->biBitCount = 32;
- break;
- case GST_VIDEO_FORMAT_BGRx:
- amt->subtype = MEDIASUBTYPE_RGB32;
- bih->biBitCount = 32;
- break;
- case GST_VIDEO_FORMAT_BGR:
- amt->subtype = MEDIASUBTYPE_RGB24;
- bih->biBitCount = 24;
- break;
- case GST_VIDEO_FORMAT_RGB16:
- amt->subtype = MEDIASUBTYPE_RGB565;
- amt->cbFormat = offsetof(VIDEOINFO, u.dwBitMasks[3]);
- vih->u.dwBitMasks[iRED] = 0xf800;
- vih->u.dwBitMasks[iGREEN] = 0x07e0;
- vih->u.dwBitMasks[iBLUE] = 0x001f;
- bih->biBitCount = 16;
- bih->biCompression = BI_BITFIELDS;
- break;
- case GST_VIDEO_FORMAT_RGB15:
- amt->subtype = MEDIASUBTYPE_RGB555;
- bih->biBitCount = 16;
- break;
- default:
- WARN("Cannot convert %s to a DirectShow type.\n", GST_VIDEO_INFO_NAME(info));
- CoTaskMemFree(vih);
- return FALSE;
- }
- } else {
- amt->subtype = MEDIATYPE_Video;
- if (!(amt->subtype.Data1 = gst_video_format_to_fourcc(GST_VIDEO_INFO_FORMAT(info))))
- {
- CoTaskMemFree(vih);
- return 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'):
- bih->biBitCount = 12; break;
- case mmioFOURCC('Y','U','Y','2'):
- case mmioFOURCC('Y','V','Y','U'):
- case mmioFOURCC('U','Y','V','Y'):
- bih->biBitCount = 16; break;
- }
- bih->biCompression = amt->subtype.Data1;
- }
- bih->biSizeImage = GST_VIDEO_INFO_SIZE(info);
- if ((vih->AvgTimePerFrame = (REFERENCE_TIME)MulDiv(10000000,
- GST_VIDEO_INFO_FPS_D(info), GST_VIDEO_INFO_FPS_N(info))) == -1)
- vih->AvgTimePerFrame = 0; /* zero division or integer overflow */
- bih->biSize = sizeof(*bih);
- bih->biWidth = width;
- bih->biHeight = height;
- bih->biPlanes = 1;
- return TRUE;
-}
-
static enum wg_audio_format wg_audio_format_from_gst(GstAudioFormat format)
{
switch (format)
@@ -1281,7 +1135,8 @@ static gboolean event_sink(GstPad *pad, GstObject *parent, GstEvent *event)
gst_event_parse_caps(event, &caps);
pthread_mutex_lock(&parser->mutex);
- gst_caps_replace(&stream->caps, caps);
+ wg_format_from_caps(&stream->preferred_format, caps);
+ stream->has_caps = true;
pthread_mutex_unlock(&parser->mutex);
pthread_cond_signal(&parser->init_cond);
break;
@@ -2080,7 +1935,7 @@ static HRESULT GST_Connect(struct parser *This, IPin *pConnectPin)
stream->duration = query_duration(stream->their_src);
pin->seek.llDuration = pin->seek.llStop = stream->duration;
pin->seek.llCurrent = 0;
- while (!stream->caps && !parser->error)
+ while (!stream->has_caps && !parser->error)
pthread_cond_wait(&parser->init_cond, &parser->mutex);
if (parser->error)
{
@@ -2375,67 +2230,47 @@ static HRESULT decodebin_parser_source_get_media_type(struct parser_source *pin,
unsigned int index, AM_MEDIA_TYPE *mt)
{
struct wg_parser_stream *stream = pin->wg_stream;
- const GstCaps *caps = stream->caps;
- const GstStructure *structure;
- const char *type;
+ struct wg_format format = stream->preferred_format;
- static const GstVideoFormat video_formats[] =
+ static const enum wg_video_format video_formats[] =
{
/* Try to prefer YUV formats over RGB ones. Most decoders output in the
* YUV color space, and it's generally much less expensive for
* videoconvert to do YUV -> YUV transformations. */
- GST_VIDEO_FORMAT_AYUV,
- GST_VIDEO_FORMAT_I420,
- GST_VIDEO_FORMAT_YV12,
- GST_VIDEO_FORMAT_YUY2,
- GST_VIDEO_FORMAT_UYVY,
- GST_VIDEO_FORMAT_YVYU,
- GST_VIDEO_FORMAT_NV12,
- GST_VIDEO_FORMAT_BGRA,
- GST_VIDEO_FORMAT_BGRx,
- GST_VIDEO_FORMAT_BGR,
- GST_VIDEO_FORMAT_RGB16,
- GST_VIDEO_FORMAT_RGB15,
+ WG_VIDEO_FORMAT_AYUV,
+ WG_VIDEO_FORMAT_I420,
+ WG_VIDEO_FORMAT_YV12,
+ WG_VIDEO_FORMAT_YUY2,
+ WG_VIDEO_FORMAT_UYVY,
+ WG_VIDEO_FORMAT_YVYU,
+ WG_VIDEO_FORMAT_NV12,
+ WG_VIDEO_FORMAT_BGRA,
+ WG_VIDEO_FORMAT_BGRx,
+ WG_VIDEO_FORMAT_BGR,
+ WG_VIDEO_FORMAT_RGB16,
+ WG_VIDEO_FORMAT_RGB15,
};
- 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))
+ if (amt_from_wg_format(mt, &format))
{
if (!index--)
return S_OK;
FreeMediaType(mt);
}
- if (!strcmp(type, "video/x-raw") && index < ARRAY_SIZE(video_formats))
+ if (format.major_type == WG_MAJOR_TYPE_VIDEO && index < ARRAY_SIZE(video_formats))
{
- gint width, height, fps_n, fps_d;
- GstVideoInfo info;
-
- 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 (gst_structure_get_fraction(structure, "framerate", &fps_n, &fps_d) && fps_n)
- {
- info.fps_n = fps_n;
- info.fps_d = fps_d;
- }
- if (!amt_from_gst_video_info(&info, mt))
+ format.u.video.format = video_formats[index];
+ if (!amt_from_wg_format(mt, &format))
return E_OUTOFMEMORY;
return S_OK;
}
- else if (!strcmp(type, "audio/x-raw") && !index)
+ else if (format.major_type == WG_MAJOR_TYPE_AUDIO && !index)
{
- GstAudioInfo info;
- gint rate;
-
- 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))
+ format.u.audio.format = WG_AUDIO_FORMAT_S16LE;
+ if (!amt_from_wg_format(mt, &format))
return E_OUTOFMEMORY;
return S_OK;
}
@@ -3152,7 +2987,7 @@ static HRESULT wave_parser_source_query_accept(struct parser_source *pin, const
AM_MEDIA_TYPE pad_mt;
HRESULT hr;
- if (!amt_from_gst_caps(stream->caps, &pad_mt))
+ if (!amt_from_wg_format(&pad_mt, &stream->preferred_format))
return E_OUTOFMEMORY;
hr = compare_media_types(mt, &pad_mt) ? S_OK : S_FALSE;
FreeMediaType(&pad_mt);
@@ -3166,7 +3001,7 @@ static HRESULT wave_parser_source_get_media_type(struct parser_source *pin,
if (index > 0)
return VFW_S_NO_MORE_ITEMS;
- if (!amt_from_gst_caps(stream->caps, mt))
+ if (!amt_from_wg_format(mt, &stream->preferred_format))
return E_OUTOFMEMORY;
return S_OK;
}
@@ -3273,7 +3108,7 @@ static HRESULT avi_splitter_source_query_accept(struct parser_source *pin, const
AM_MEDIA_TYPE pad_mt;
HRESULT hr;
- if (!amt_from_gst_caps(stream->caps, &pad_mt))
+ if (!amt_from_wg_format(&pad_mt, &stream->preferred_format))
return E_OUTOFMEMORY;
hr = compare_media_types(mt, &pad_mt) ? S_OK : S_FALSE;
FreeMediaType(&pad_mt);
@@ -3287,7 +3122,7 @@ static HRESULT avi_splitter_source_get_media_type(struct parser_source *pin,
if (index > 0)
return VFW_S_NO_MORE_ITEMS;
- if (!amt_from_gst_caps(stream->caps, mt))
+ if (!amt_from_wg_format(mt, &stream->preferred_format))
return E_OUTOFMEMORY;
return S_OK;
}
@@ -3404,7 +3239,7 @@ static HRESULT mpeg_splitter_source_query_accept(struct parser_source *pin, cons
AM_MEDIA_TYPE pad_mt;
HRESULT hr;
- if (!amt_from_gst_caps(stream->caps, &pad_mt))
+ if (!amt_from_wg_format(&pad_mt, &stream->preferred_format))
return E_OUTOFMEMORY;
hr = compare_media_types(mt, &pad_mt) ? S_OK : S_FALSE;
FreeMediaType(&pad_mt);
@@ -3418,7 +3253,7 @@ static HRESULT mpeg_splitter_source_get_media_type(struct parser_source *pin,
if (index > 0)
return VFW_S_NO_MORE_ITEMS;
- if (!amt_from_gst_caps(stream->caps, mt))
+ if (!amt_from_wg_format(mt, &stream->preferred_format))
return E_OUTOFMEMORY;
return S_OK;
}
--
2.30.0
More information about the wine-devel
mailing list