[PATCH v3 3/3] winegstreamer: Negotiate allocators per source pin.

Zebediah Figura z.figura12 at gmail.com
Thu Feb 13 22:55:56 CST 2020


In particular, pass the correct buffer size for the format we have chosen.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48570
Fixes: f5a1e2bd87754a2822f2eb0e84291d787936d115
Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/winegstreamer/gstdemux.c | 91 ++++++++---------------------------
 1 file changed, 19 insertions(+), 72 deletions(-)

diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c
index b62f44b6a13..1337cd0a81c 100644
--- a/dlls/winegstreamer/gstdemux.c
+++ b/dlls/winegstreamer/gstdemux.c
@@ -57,7 +57,6 @@ struct gstdemux
 
     struct strmbase_sink sink;
     IAsyncReader *reader;
-    IMemAllocator *alloc;
 
     struct gstdemux_source **sources;
     unsigned int source_count;
@@ -70,7 +69,6 @@ struct gstdemux
     GstPad *my_src, *their_sink;
     GstBus *bus;
     guint64 start, nextofs, nextpullofs, stop;
-    ALLOCATOR_PROPERTIES props;
     HANDLE no_more_pads_event, duration_event, error_event;
 
     HANDLE push_thread;
@@ -486,11 +484,6 @@ static gboolean setcaps_sink(GstPad *pad, GstCaps *caps)
     if (!amt_from_gst_caps(caps, &pin->mt))
         return FALSE;
 
-    if (IsEqualGUID(&pin->mt.formattype, &FORMAT_VideoInfo))
-    {
-        VIDEOINFOHEADER *vih = (VIDEOINFOHEADER *)pin->mt.pbFormat;
-        filter->props.cbBuffer = max(filter->props.cbBuffer, vih->bmiHeader.biSizeImage);
-    }
     SetEvent(pin->caps_event);
     return TRUE;
 }
@@ -1295,7 +1288,7 @@ static void unknown_type(GstElement *bin, GstPad *pad, GstCaps *caps, gpointer u
     g_free(strcaps);
 }
 
-static HRESULT GST_Connect(struct gstdemux *This, IPin *pConnectPin, ALLOCATOR_PROPERTIES *props)
+static HRESULT GST_Connect(struct gstdemux *This, IPin *pConnectPin)
 {
     LONGLONG avail;
     GstStaticPadTemplate src_template = GST_STATIC_PAD_TEMPLATE(
@@ -1304,7 +1297,6 @@ static HRESULT GST_Connect(struct gstdemux *This, IPin *pConnectPin, ALLOCATOR_P
         GST_PAD_ALWAYS,
         GST_STATIC_CAPS_ANY);
 
-    This->props = *props;
     IAsyncReader_Length(This->reader, &This->filesize, &avail);
 
     if (!This->bus) {
@@ -1329,7 +1321,6 @@ static HRESULT GST_Connect(struct gstdemux *This, IPin *pConnectPin, ALLOCATOR_P
         return E_FAIL;
     This->initial = FALSE;
 
-    *props = This->props;
     This->nextofs = This->nextpullofs = 0;
     return S_OK;
 }
@@ -1378,9 +1369,6 @@ static void gstdemux_destroy(struct strmbase_filter *iface)
         assert(hr == S_OK);
     }
 
-    if (filter->alloc)
-        IMemAllocator_Release(filter->alloc);
-    filter->alloc = NULL;
     if (filter->reader)
         IAsyncReader_Release(filter->reader);
     filter->reader = NULL;
@@ -1529,46 +1517,16 @@ static HRESULT sink_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE
 static HRESULT gstdemux_sink_connect(struct strmbase_sink *iface, IPin *peer, const AM_MEDIA_TYPE *pmt)
 {
     struct gstdemux *filter = impl_from_strmbase_sink(iface);
-    IMemAllocator *allocator = NULL;
-    ALLOCATOR_PROPERTIES props;
     HRESULT hr = S_OK;
 
     mark_wine_thread();
 
-    props.cBuffers = 8;
-    props.cbBuffer = 16384;
-    props.cbAlign = 1;
-    props.cbPrefix = 0;
-
     filter->reader = NULL;
-    filter->alloc = NULL;
     if (FAILED(hr = IPin_QueryInterface(peer, &IID_IAsyncReader, (void **)&filter->reader)))
         return hr;
 
-    if (FAILED(hr = GST_Connect(filter, peer, &props)))
-        goto err;
-
-    /* Some applications depend on IAsyncReader::RequestAllocator() passing a
-     * non-NULL preferred allocator. */
-    hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC,
-            &IID_IMemAllocator, (void **)&allocator);
-    if (FAILED(hr))
-        goto err;
-    hr = IAsyncReader_RequestAllocator(filter->reader, allocator, &props, &filter->alloc);
-    IMemAllocator_Release(allocator);
-    if (FAILED(hr))
-    {
-        WARN("Failed to get allocator, hr %#x.\n", hr);
-        goto err;
-    }
-
-    if (FAILED(hr = IMemAllocator_Commit(filter->alloc)))
-    {
-        WARN("Failed to commit allocator, hr %#x.\n", hr);
-        IMemAllocator_Release(filter->alloc);
-        filter->alloc = NULL;
+    if (FAILED(hr = GST_Connect(filter, peer)))
         goto err;
-    }
 
     return S_OK;
 err:
@@ -1584,7 +1542,6 @@ static void gstdemux_sink_disconnect(struct strmbase_sink *iface)
 
     mark_wine_thread();
 
-    IMemAllocator_Decommit(filter->alloc);
     GST_RemoveOutputPins(filter);
 }
 
@@ -2083,37 +2040,27 @@ static HRESULT source_get_media_type(struct strmbase_pin *iface, unsigned int in
 }
 
 static HRESULT WINAPI GSTOutPin_DecideBufferSize(struct strmbase_source *iface,
-        IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *ppropInputRequest)
+        IMemAllocator *allocator, ALLOCATOR_PROPERTIES *props)
 {
-    struct gstdemux_source *This = impl_source_from_IPin(&iface->pin.IPin_iface);
-    TRACE("(%p)->(%p, %p)\n", This, pAlloc, ppropInputRequest);
-    /* Unused */
-    return S_OK;
-}
-
-static HRESULT WINAPI GSTOutPin_DecideAllocator(struct strmbase_source *base,
-        IMemInputPin *pPin, IMemAllocator **pAlloc)
-{
-    struct gstdemux_source *pin = impl_source_from_IPin(&base->pin.IPin_iface);
-    struct gstdemux *filter = impl_from_strmbase_filter(pin->pin.pin.filter);
-    HRESULT hr;
-
-    TRACE("pin %p, peer %p, allocator %p.\n", pin, pPin, pAlloc);
+    struct gstdemux_source *pin = impl_source_from_IPin(&iface->pin.IPin_iface);
+    unsigned int buffer_size = 16384;
+    ALLOCATOR_PROPERTIES ret_props;
 
-    *pAlloc = NULL;
-    if (filter->alloc)
+    if (IsEqualGUID(&pin->pin.pin.mt.formattype, &FORMAT_VideoInfo))
     {
-        hr = IMemInputPin_NotifyAllocator(pPin, filter->alloc, FALSE);
-        if (SUCCEEDED(hr))
-        {
-            *pAlloc = filter->alloc;
-            IMemAllocator_AddRef(*pAlloc);
-        }
+        VIDEOINFOHEADER *format = (VIDEOINFOHEADER *)pin->pin.pin.mt.pbFormat;
+        buffer_size = format->bmiHeader.biSizeImage;
+    }
+    else if (IsEqualGUID(&pin->pin.pin.mt.formattype, &FORMAT_WaveFormatEx))
+    {
+        WAVEFORMATEX *format = (WAVEFORMATEX *)pin->pin.pin.mt.pbFormat;
+        buffer_size = format->nAvgBytesPerSec;
     }
-    else
-        hr = VFW_E_NO_ALLOCATOR;
 
-    return hr;
+    props->cBuffers = max(props->cBuffers, 1);
+    props->cbBuffer = max(props->cbBuffer, buffer_size);
+    props->cbAlign = max(props->cbAlign, 1);
+    return IMemAllocator_SetProperties(allocator, props, &ret_props);
 }
 
 static void free_source_pin(struct gstdemux_source *pin)
@@ -2155,8 +2102,8 @@ static const struct strmbase_source_ops source_ops =
     .base.pin_query_accept = source_query_accept,
     .base.pin_get_media_type = source_get_media_type,
     .pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection,
+    .pfnDecideAllocator = BaseOutputPinImpl_DecideAllocator,
     .pfnDecideBufferSize = GSTOutPin_DecideBufferSize,
-    .pfnDecideAllocator = GSTOutPin_DecideAllocator,
 };
 
 static struct gstdemux_source *create_pin(struct gstdemux *filter, const WCHAR *name)
-- 
2.25.0




More information about the wine-devel mailing list