[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