gldownload: Fix renegotiation loop

When DMABuf was tried, we would renegotiate back and fourth between
DMABuf and system memory if the export failed. This would happen for
every single frame.

This patch introduces try_dmabuf_exports boolean, which is unset when
an export failed. This boolean is then put back to TRUE when upstream
pushes new caps, or downstream pushes a reconfigure event.
This commit is contained in:
Nicolas Dufresne 2019-11-10 20:05:59 -05:00
parent a09674dd6d
commit 95abc6c263
2 changed files with 61 additions and 2 deletions

View file

@ -45,6 +45,8 @@ static gboolean gst_gl_download_element_get_unit_size (GstBaseTransform * trans,
GstCaps * caps, gsize * size);
static GstCaps *gst_gl_download_element_transform_caps (GstBaseTransform * bt,
GstPadDirection direction, GstCaps * caps, GstCaps * filter);
static GstCaps *gst_gl_download_element_fixate_caps (GstBaseTransform * trans,
GstPadDirection direction, GstCaps * caps, GstCaps * othercaps);
static gboolean gst_gl_download_element_set_caps (GstBaseTransform * bt,
GstCaps * in_caps, GstCaps * out_caps);
static GstFlowReturn
@ -89,12 +91,15 @@ gst_gl_download_element_class_init (GstGLDownloadElementClass * klass)
bt_class->start = gst_gl_download_element_start;
bt_class->stop = gst_gl_download_element_stop;
bt_class->transform_caps = gst_gl_download_element_transform_caps;
bt_class->fixate_caps = gst_gl_download_element_fixate_caps;
bt_class->set_caps = gst_gl_download_element_set_caps;
bt_class->get_unit_size = gst_gl_download_element_get_unit_size;
bt_class->prepare_output_buffer =
gst_gl_download_element_prepare_output_buffer;
bt_class->transform = gst_gl_download_element_transform;
bt_class->decide_allocation = gst_gl_download_element_decide_allocation;
bt_class->sink_event = gst_gl_download_element_sink_event;
bt_class->src_event = gst_gl_download_element_src_event;
bt_class->passthrough_on_same_caps = TRUE;
@ -124,6 +129,7 @@ gst_gl_download_element_start (GstBaseTransform * bt)
GstGLDownloadElement *dl = GST_GL_DOWNLOAD_ELEMENT (bt);
dl->dmabuf_allocator = gst_dmabuf_allocator_new ();
g_atomic_int_set (&dl->try_dmabuf_exports, TRUE);
#endif
return TRUE;
@ -158,8 +164,8 @@ gst_gl_download_element_set_caps (GstBaseTransform * bt, GstCaps * in_caps,
if (gst_caps_features_contains (features, GST_CAPS_FEATURE_MEMORY_GL_MEMORY)) {
dl->mode = GST_GL_DOWNLOAD_MODE_PASSTHROUGH;
#if GST_GL_HAVE_PLATFORM_EGL && GST_GL_HAVE_DMABUF
} else if (gst_caps_features_contains (features,
GST_CAPS_FEATURE_MEMORY_DMABUF)) {
} else if (g_atomic_int_get (&dl->try_dmabuf_exports) &&
gst_caps_features_contains (features, GST_CAPS_FEATURE_MEMORY_DMABUF)) {
dl->mode = GST_GL_DOWNLOAD_MODE_DMABUF_EXPORTS;
#endif
} else {
@ -232,6 +238,33 @@ gst_gl_download_element_transform_caps (GstBaseTransform * bt,
return result;
}
static GstCaps *
gst_gl_download_element_fixate_caps (GstBaseTransform * bt,
GstPadDirection direction, GstCaps * caps, GstCaps * othercaps)
{
#if GST_GL_HAVE_PLATFORM_EGL && GST_GL_HAVE_DMABUF
GstGLDownloadElement *dl = GST_GL_DOWNLOAD_ELEMENT (bt);
/* Remove DMABuf features if try_dmabuf_exports is not set */
if (direction == GST_PAD_SINK && !g_atomic_int_get (&dl->try_dmabuf_exports)) {
gint i;
for (i = 0; i < gst_caps_get_size (othercaps); i++) {
GstCapsFeatures *features = gst_caps_get_features (othercaps, i);
if (features && gst_caps_features_contains (features,
GST_CAPS_FEATURE_MEMORY_DMABUF)) {
caps = gst_caps_make_writable (othercaps);
gst_caps_remove_structure (othercaps, i--);
}
}
}
#endif
return GST_BASE_TRANSFORM_CLASS (parent_class)->fixate_caps (bt, direction,
caps, othercaps);
}
static gboolean
gst_gl_download_element_get_unit_size (GstBaseTransform * trans, GstCaps * caps,
gsize * size)
@ -453,6 +486,7 @@ gst_gl_download_element_prepare_output_buffer (GstBaseTransform * bt,
src_caps = gst_caps_make_writable (src_caps);
features = gst_caps_get_features (src_caps, 0);
gst_caps_features_remove (features, GST_CAPS_FEATURE_MEMORY_DMABUF);
g_atomic_int_set (&dl->try_dmabuf_exports, FALSE);
dl->mode = GST_GL_DOWNLOAD_MODE_PBO_TRANSFERS;
if (!gst_base_transform_update_src_caps (bt, src_caps)) {
@ -500,6 +534,30 @@ gst_gl_download_element_decide_allocation (GstBaseTransform * trans,
query);
}
static gboolean
gst_gl_download_element_sink_event (GstBaseTransform * bt, GstEvent * event)
{
GstGLDownloadElement *dl = GST_GL_DOWNLOAD_ELEMENT (bt);
/* Retry exporting whenever we have new caps from upstream */
if (GST_EVENT_TYPE (event) == GST_EVENT_CAPS)
g_atomic_int_set (&dl->try_dmabuf_exports, TRUE);
return GST_BASE_TRANSFORM_CLASS (parent_class)->sink_event (bt, event);
}
static gboolean
gst_gl_download_element_src_event (GstBaseTransform * bt, GstEvent * event)
{
GstGLDownloadElement *dl = GST_GL_DOWNLOAD_ELEMENT (bt);
/* Retry exporting whenever downstream have changed */
if (GST_EVENT_TYPE (event) == GST_EVENT_RECONFIGURE)
g_atomic_int_set (&dl->try_dmabuf_exports, TRUE);
return GST_BASE_TRANSFORM_CLASS (parent_class)->src_event (bt, event);
}
static void
gst_gl_download_element_finalize (GObject * object)
{

View file

@ -51,6 +51,7 @@ struct _GstGLDownloadElement
GstGLBaseFilter parent;
GstGlDownloadMode mode;
gboolean try_dmabuf_exports;
GstAllocator * dmabuf_allocator;
gboolean add_videometa;
};