From b8c5a4c9ed91abbbb5e57b5d7e62115e0448a9be Mon Sep 17 00:00:00 2001 From: Nicolas Dufresne Date: Thu, 18 May 2017 11:54:31 +0200 Subject: [PATCH] kmssink: drop last rendered buffer on ALLOCATION and DRAIN queries kmssink keeps a reference on the last rendered buffer. If this buffer refers to an upstream buffer, it should be should be released on DRAIN and ALLOCATION queries so all upstream buffers can be returned to the pool if needed. As the buffer may be used for scanout, we copy this buffer into a dumb buffer prior to let it go. Based on patch from Guillaume Desmottes https://bugzilla.gnome.org/show_bug.cgi?id=782774 --- sys/kms/gstkmssink.c | 47 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/sys/kms/gstkmssink.c b/sys/kms/gstkmssink.c index 639d30d8fb..253fb22f84 100644 --- a/sys/kms/gstkmssink.c +++ b/sys/kms/gstkmssink.c @@ -70,6 +70,8 @@ G_DEFINE_TYPE_WITH_CODE (GstKMSSink, gst_kms_sink, GST_TYPE_VIDEO_SINK, GST_PLUGIN_DESC); GST_DEBUG_CATEGORY_GET (CAT_PERFORMANCE, "GST_PERFORMANCE")); +static void gst_kms_sink_drain (GstKMSSink * self); + enum { PROP_DRIVER_NAME = 1, @@ -825,6 +827,11 @@ gst_kms_sink_set_caps (GstBaseSink * bsink, GstCaps * caps) self = GST_KMS_SINK (bsink); + /* We are going to change the internal buffer pool, which means it will no + * longer be compatbile with the last_buffer size. Drain now, as we won't be + * able to do that later on. */ + gst_kms_sink_drain (self); + if (!gst_video_info_from_caps (&vinfo, caps)) goto invalid_format; @@ -1336,6 +1343,45 @@ no_disp_ratio: } } +static void +gst_kms_sink_drain (GstKMSSink * self) +{ + GstParentBufferMeta *parent_meta; + + GST_DEBUG_OBJECT (self, "draining"); + + if (!self->last_buffer) + return; + + /* We only need to return the last_buffer if it depends on upstream buffer. + * In this case, the last_buffer will have a GstParentBufferMeta set. */ + parent_meta = gst_buffer_get_parent_buffer_meta (self->last_buffer); + if (parent_meta) { + GstBuffer *dumb_buf; + dumb_buf = gst_kms_sink_copy_to_dumb_buffer (self, parent_meta->buffer); + gst_kms_sink_show_frame (GST_VIDEO_SINK (self), dumb_buf); + } +} + +static gboolean +gst_kms_sink_query (GstBaseSink * bsink, GstQuery * query) +{ + GstKMSSink *self = GST_KMS_SINK (bsink); + + switch (GST_QUERY_TYPE (query)) { + case GST_QUERY_ALLOCATION: + case GST_QUERY_DRAIN: + { + gst_kms_sink_drain (self); + break; + } + default: + break; + } + + return GST_BASE_SINK_CLASS (parent_class)->query (bsink, query); +} + static void gst_kms_sink_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec) @@ -1440,6 +1486,7 @@ gst_kms_sink_class_init (GstKMSSinkClass * klass) basesink_class->set_caps = GST_DEBUG_FUNCPTR (gst_kms_sink_set_caps); basesink_class->get_caps = GST_DEBUG_FUNCPTR (gst_kms_sink_get_caps); basesink_class->propose_allocation = gst_kms_sink_propose_allocation; + basesink_class->query = gst_kms_sink_query; videosink_class->show_frame = gst_kms_sink_show_frame;