[PATCH 3/4] winegstreamer: Use struct wg_format to convert from AM_MEDIA_TYPE to GstCaps.
Zebediah Figura
z.figura12 at gmail.com
Mon Feb 8 15:07:00 CST 2021
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
dlls/winegstreamer/gstdemux.c | 222 +++++++++++++++++++++++++---------
1 file changed, 167 insertions(+), 55 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c
index 96405f89e53..73458d9210e 100644
--- a/dlls/winegstreamer/gstdemux.c
+++ b/dlls/winegstreamer/gstdemux.c
@@ -782,105 +782,217 @@ static bool amt_from_gst_caps(const GstCaps *caps, AM_MEDIA_TYPE *mt)
return amt_from_wg_format(mt, &wg_format);
}
-static GstCaps *amt_to_gst_caps_video(const AM_MEDIA_TYPE *mt)
+static bool amt_to_wg_format_audio(const AM_MEDIA_TYPE *mt, struct wg_format *format)
{
static const struct
{
const GUID *subtype;
- GstVideoFormat format;
+ WORD depth;
+ enum wg_audio_format 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_RGB16},
- {&MEDIASUBTYPE_RGB555, GST_VIDEO_FORMAT_RGB15},
+ {&MEDIASUBTYPE_PCM, 8, WG_AUDIO_FORMAT_U8},
+ {&MEDIASUBTYPE_PCM, 16, WG_AUDIO_FORMAT_S16LE},
+ {&MEDIASUBTYPE_PCM, 24, WG_AUDIO_FORMAT_S24LE},
+ {&MEDIASUBTYPE_PCM, 32, WG_AUDIO_FORMAT_S32LE},
+ {&MEDIASUBTYPE_IEEE_FLOAT, 32, WG_AUDIO_FORMAT_F32LE},
+ {&MEDIASUBTYPE_IEEE_FLOAT, 64, WG_AUDIO_FORMAT_F64LE},
};
- const VIDEOINFOHEADER *vih = (VIDEOINFOHEADER *)mt->pbFormat;
- GstVideoFormat format = GST_VIDEO_FORMAT_UNKNOWN;
- GstVideoInfo info;
+ const WAVEFORMATEX *audio_format = (const WAVEFORMATEX *)mt->pbFormat;
unsigned int i;
- GstCaps *caps;
- if (!IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo)
- || mt->cbFormat < sizeof(VIDEOINFOHEADER) || !mt->pbFormat)
- return NULL;
+ if (!IsEqualGUID(&mt->formattype, &FORMAT_WaveFormatEx))
+ {
+ FIXME("Unknown format type %s.\n", debugstr_guid(&mt->formattype));
+ return false;
+ }
+ if (mt->cbFormat < sizeof(WAVEFORMATEX) || !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->nChannels;
+ format->u.audio.rate = audio_format->nSamplesPerSec;
for (i = 0; i < ARRAY_SIZE(format_map); ++i)
{
- if (IsEqualGUID(&mt->subtype, format_map[i].subtype))
+ if (IsEqualGUID(&mt->subtype, format_map[i].subtype)
+ && audio_format->wBitsPerSample == format_map[i].depth)
{
- format = format_map[i].format;
- break;
+ format->u.audio.format = format_map[i].format;
+ return true;
}
}
- if (format == GST_VIDEO_FORMAT_UNKNOWN)
- format = gst_video_format_from_fourcc(vih->bmiHeader.biCompression);
+ FIXME("Unknown subtype %s, depth %u.\n", debugstr_guid(&mt->subtype), audio_format->wBitsPerSample);
+ return false;
+}
- if (format == GST_VIDEO_FORMAT_UNKNOWN)
+static bool amt_to_wg_format_video(const AM_MEDIA_TYPE *mt, struct wg_format *format)
+{
+ static const struct
{
- FIXME("Unknown video format (subtype %s, compression %#x).\n",
- debugstr_guid(&mt->subtype), vih->bmiHeader.biCompression);
- return NULL;
+ const GUID *subtype;
+ enum wg_video_format format;
}
+ format_map[] =
+ {
+ {&MEDIASUBTYPE_ARGB32, WG_VIDEO_FORMAT_BGRA},
+ {&MEDIASUBTYPE_RGB32, WG_VIDEO_FORMAT_BGRx},
+ {&MEDIASUBTYPE_RGB24, WG_VIDEO_FORMAT_BGR},
+ {&MEDIASUBTYPE_RGB555, WG_VIDEO_FORMAT_RGB15},
+ {&MEDIASUBTYPE_RGB565, WG_VIDEO_FORMAT_RGB16},
+ {&MEDIASUBTYPE_AYUV, WG_VIDEO_FORMAT_AYUV},
+ {&MEDIASUBTYPE_I420, WG_VIDEO_FORMAT_I420},
+ {&MEDIASUBTYPE_NV12, WG_VIDEO_FORMAT_NV12},
+ {&MEDIASUBTYPE_UYVY, WG_VIDEO_FORMAT_UYVY},
+ {&MEDIASUBTYPE_YUY2, WG_VIDEO_FORMAT_YUY2},
+ {&MEDIASUBTYPE_YV12, WG_VIDEO_FORMAT_YV12},
+ {&MEDIASUBTYPE_YVYU, WG_VIDEO_FORMAT_YVYU},
+ {&MEDIASUBTYPE_CVID, WG_VIDEO_FORMAT_CINEPAK},
+ };
- gst_video_info_set_format(&info, format, vih->bmiHeader.biWidth, vih->bmiHeader.biHeight);
- if ((caps = gst_video_info_to_caps(&info)))
+ const VIDEOINFOHEADER *video_format = (const VIDEOINFOHEADER *)mt->pbFormat;
+ unsigned int i;
+
+ if (!IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo))
{
- /* Clear some fields that shouldn't prevent us from connecting. */
- for (i = 0; i < gst_caps_get_size(caps); ++i)
+ FIXME("Unknown format type %s.\n", debugstr_guid(&mt->formattype));
+ return false;
+ }
+ if (mt->cbFormat < sizeof(VIDEOINFOHEADER) || !mt->pbFormat)
+ {
+ ERR("Unexpected format size %u.\n", mt->cbFormat);
+ return false;
+ }
+
+ format->major_type = WG_MAJOR_TYPE_VIDEO;
+ format->u.video.width = video_format->bmiHeader.biWidth;
+ format->u.video.height = video_format->bmiHeader.biHeight;
+ format->u.video.fps_n = 10000000;
+ format->u.video.fps_d = video_format->AvgTimePerFrame;
+
+ for (i = 0; i < ARRAY_SIZE(format_map); ++i)
+ {
+ if (IsEqualGUID(&mt->subtype, format_map[i].subtype))
{
- gst_structure_remove_fields(gst_caps_get_structure(caps, i),
- "framerate", "pixel-aspect-ratio", "colorimetry", "chroma-site", NULL);
+ format->u.video.format = format_map[i].format;
+ return true;
}
}
- return caps;
+
+ FIXME("Unknown subtype %s.\n", debugstr_guid(&mt->subtype));
+ return false;
+}
+
+static bool amt_to_wg_format(const AM_MEDIA_TYPE *mt, struct wg_format *format)
+{
+ memset(format, 0, sizeof(*format));
+
+ if (IsEqualGUID(&mt->majortype, &MEDIATYPE_Video))
+ return amt_to_wg_format_video(mt, format);
+ if (IsEqualGUID(&mt->majortype, &MEDIATYPE_Audio))
+ return amt_to_wg_format_audio(mt, format);
+
+ FIXME("Unknown major type %s.\n", debugstr_guid(&mt->majortype));
+ return false;
+}
+
+static GstAudioFormat wg_audio_format_to_gst(enum wg_audio_format format)
+{
+ switch (format)
+ {
+ case WG_AUDIO_FORMAT_U8: return GST_AUDIO_FORMAT_U8;
+ case WG_AUDIO_FORMAT_S16LE: return GST_AUDIO_FORMAT_S16LE;
+ case WG_AUDIO_FORMAT_S24LE: return GST_AUDIO_FORMAT_S24LE;
+ case WG_AUDIO_FORMAT_S32LE: return GST_AUDIO_FORMAT_S32LE;
+ case WG_AUDIO_FORMAT_F32LE: return GST_AUDIO_FORMAT_F32LE;
+ case WG_AUDIO_FORMAT_F64LE: return GST_AUDIO_FORMAT_F64LE;
+ default: return GST_AUDIO_FORMAT_UNKNOWN;
+ }
}
-static GstCaps *amt_to_gst_caps_audio(const AM_MEDIA_TYPE *mt)
+static GstCaps *wg_format_to_caps_audio(const struct wg_format *format)
{
- const WAVEFORMATEX *wfx = (WAVEFORMATEX *)mt->pbFormat;
- GstAudioFormat format = GST_AUDIO_FORMAT_UNKNOWN;
+ GstAudioFormat audio_format;
GstAudioInfo info;
- if (!IsEqualGUID(&mt->formattype, &FORMAT_WaveFormatEx)
- || mt->cbFormat < sizeof(WAVEFORMATEX) || !mt->pbFormat)
+ if ((audio_format = wg_audio_format_to_gst(format->u.audio.format)) == GST_AUDIO_FORMAT_UNKNOWN)
return NULL;
- 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))
+ gst_audio_info_set_format(&info, audio_format, format->u.audio.rate, format->u.audio.channels, NULL);
+ return gst_audio_info_to_caps(&info);
+}
+
+static GstVideoFormat wg_video_format_to_gst(enum wg_video_format format)
+{
+ switch (format)
{
- if (wfx->wBitsPerSample == 32)
- format = GST_AUDIO_FORMAT_F32LE;
- else if (wfx->wBitsPerSample == 64)
- format = GST_AUDIO_FORMAT_F64LE;
+ case WG_VIDEO_FORMAT_BGRA: return GST_VIDEO_FORMAT_BGRA;
+ case WG_VIDEO_FORMAT_BGRx: return GST_VIDEO_FORMAT_BGRx;
+ case WG_VIDEO_FORMAT_BGR: return GST_VIDEO_FORMAT_BGR;
+ case WG_VIDEO_FORMAT_RGB15: return GST_VIDEO_FORMAT_RGB15;
+ case WG_VIDEO_FORMAT_RGB16: return GST_VIDEO_FORMAT_RGB16;
+ case WG_VIDEO_FORMAT_AYUV: return GST_VIDEO_FORMAT_AYUV;
+ case WG_VIDEO_FORMAT_I420: return GST_VIDEO_FORMAT_I420;
+ case WG_VIDEO_FORMAT_NV12: return GST_VIDEO_FORMAT_NV12;
+ case WG_VIDEO_FORMAT_UYVY: return GST_VIDEO_FORMAT_UYVY;
+ case WG_VIDEO_FORMAT_YUY2: return GST_VIDEO_FORMAT_YUY2;
+ case WG_VIDEO_FORMAT_YV12: return GST_VIDEO_FORMAT_YV12;
+ case WG_VIDEO_FORMAT_YVYU: return GST_VIDEO_FORMAT_YVYU;
+ default: return GST_VIDEO_FORMAT_UNKNOWN;
}
+}
- if (format == GST_AUDIO_FORMAT_UNKNOWN)
- {
- FIXME("Unknown audio format (subtype %s, depth %u).\n",
- debugstr_guid(&mt->subtype), wfx->wBitsPerSample);
+static GstCaps *wg_format_to_caps_video(const struct wg_format *format)
+{
+ GstVideoFormat video_format;
+ GstVideoInfo info;
+ unsigned int i;
+ GstCaps *caps;
+
+ if ((video_format = wg_video_format_to_gst(format->u.video.format)) == GST_VIDEO_FORMAT_UNKNOWN)
return NULL;
+
+ gst_video_info_set_format(&info, video_format, format->u.video.width, format->u.video.height);
+ if ((caps = gst_video_info_to_caps(&info)))
+ {
+ /* Clear some fields that shouldn't prevent us from connecting. */
+ for (i = 0; i < gst_caps_get_size(caps); ++i)
+ {
+ gst_structure_remove_fields(gst_caps_get_structure(caps, i),
+ "framerate", "pixel-aspect-ratio", "colorimetry", "chroma-site", NULL);
+ }
}
+ return caps;
+}
- gst_audio_info_set_format(&info, format, wfx->nSamplesPerSec, wfx->nChannels, NULL);
- return gst_audio_info_to_caps(&info);
+static GstCaps *wg_format_to_caps(const struct wg_format *format)
+{
+ switch (format->major_type)
+ {
+ case WG_MAJOR_TYPE_UNKNOWN:
+ return NULL;
+ case WG_MAJOR_TYPE_AUDIO:
+ return wg_format_to_caps_audio(format);
+ case WG_MAJOR_TYPE_VIDEO:
+ return wg_format_to_caps_video(format);
+ }
+ assert(0);
+ return NULL;
}
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);
+ struct wg_format wg_format;
- FIXME("Unknown major type %s.\n", debugstr_guid(&mt->majortype));
- return NULL;
+ if (!amt_to_wg_format(mt, &wg_format))
+ return NULL;
+ return wg_format_to_caps(&wg_format);
}
static gboolean query_sink(GstPad *pad, GstObject *parent, GstQuery *query)
--
2.30.0
More information about the wine-devel
mailing list