videorate: Implement allocation query
authorNicolas Dufresne <nicolas.dufresne@collabora.co.uk>
Sun, 18 Jan 2015 19:58:36 +0000 (14:58 -0500)
committerNicolas Dufresne <nicolas.dufresne@collabora.co.uk>
Sun, 18 Jan 2015 19:58:36 +0000 (14:58 -0500)
The videorate element keeps 1 buffer internally. This buffer need
to be requested during allocation query otherwise the pipeline may
stall.

https://bugzilla.gnome.org/show_bug.cgi?id=738302

gst/videorate/Makefile.am
gst/videorate/gstvideorate.c

index d950ad9840e6376420670bb2783fb82f67ca6a53..1a5631ed83a915d492b0be2fae81c23e941c6346 100644 (file)
@@ -5,7 +5,8 @@ plugin_LTLIBRARIES = libgstvideorate.la
 libgstvideorate_la_SOURCES = gstvideorate.c
 libgstvideorate_la_CFLAGS = $(GST_CFLAGS) $(GST_BASE_CFLAGS)
 libgstvideorate_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
-libgstvideorate_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS)
+libgstvideorate_la_LIBADD = $(GST_LIBS) $(GST_BASE_LIBS) \
+       $(top_builddir)/gst-libs/gst/video/libgstvideo-$(GST_API_VERSION).la
 libgstvideorate_la_LIBTOOLFLAGS = $(GST_PLUGIN_LIBTOOLFLAGS)
 
 Android.mk: Makefile.am $(BUILT_SOURCES)
index 6a20258526353e5e569f238b970514c476209c36..9d97763fd3a93e1205d3f154e75f1f8b29213361 100644 (file)
@@ -70,6 +70,7 @@
 #endif
 
 #include "gstvideorate.h"
+#include <gst/video/video.h>
 
 GST_DEBUG_CATEGORY_STATIC (video_rate_debug);
 #define GST_CAT_DEFAULT video_rate_debug
@@ -136,6 +137,9 @@ static GstCaps *gst_video_rate_fixate_caps (GstBaseTransform * trans,
 static GstFlowReturn gst_video_rate_transform_ip (GstBaseTransform * trans,
     GstBuffer * buf);
 
+static gboolean gst_video_rate_propose_allocation (GstBaseTransform * trans,
+    GstQuery * decide_query, GstQuery * query);
+
 static gboolean gst_video_rate_start (GstBaseTransform * trans);
 static gboolean gst_video_rate_stop (GstBaseTransform * trans);
 
@@ -170,6 +174,8 @@ gst_video_rate_class_init (GstVideoRateClass * klass)
   base_class->stop = GST_DEBUG_FUNCPTR (gst_video_rate_stop);
   base_class->fixate_caps = GST_DEBUG_FUNCPTR (gst_video_rate_fixate_caps);
   base_class->query = GST_DEBUG_FUNCPTR (gst_video_rate_query);
+  base_class->propose_allocation =
+      GST_DEBUG_FUNCPTR (gst_video_rate_propose_allocation);
 
   g_object_class_install_property (object_class, PROP_IN,
       g_param_spec_uint64 ("in", "In",
@@ -863,6 +869,58 @@ gst_video_rate_query (GstBaseTransform * trans, GstPadDirection direction,
   return res;
 }
 
+static gboolean
+gst_video_rate_propose_allocation (GstBaseTransform * trans,
+    GstQuery * decide_query, GstQuery * query)
+{
+  GstBaseTransformClass *klass = GST_BASE_TRANSFORM_CLASS (parent_class);
+  gboolean res;
+
+  /* We should always be passthrough */
+  g_return_val_if_fail (decide_query == NULL, FALSE);
+
+  res = klass->propose_allocation (trans, NULL, query);
+
+  if (res) {
+    guint i = 0;
+    guint n_allocation;
+    guint down_min = 0;
+
+    n_allocation = gst_query_get_n_allocation_pools (query);
+
+    while (i < n_allocation) {
+      GstBufferPool *pool;
+      guint size, min, max;
+
+      gst_query_parse_nth_allocation_pool (query, i, &pool, &size, &min, &max);
+
+      if (min == max) {
+        if (pool)
+          gst_object_unref (pool);
+        gst_query_remove_nth_allocation_pool (query, i);
+        n_allocation--;
+        down_min = MAX (min, down_min);
+        continue;
+      }
+
+      gst_query_set_nth_allocation_pool (query, i, pool, size, min + 1, max);
+      i++;
+    }
+
+    if (n_allocation == 0) {
+      GstCaps *caps;
+      GstVideoInfo info;
+
+      gst_query_parse_allocation (query, &caps, NULL);
+      gst_video_info_from_caps (&info, caps);
+
+      gst_query_add_allocation_pool (query, NULL, info.size, down_min + 1, 0);
+    }
+  }
+
+  return res;
+}
+
 static GstFlowReturn
 gst_video_rate_trans_ip_max_avg (GstVideoRate * videorate, GstBuffer * buf)
 {