query: improve scheduling query
authorWim Taymans <wim.taymans@collabora.co.uk>
Fri, 18 Nov 2011 16:27:16 +0000 (17:27 +0100)
committerWim Taymans <wim.taymans@collabora.co.uk>
Fri, 18 Nov 2011 16:27:16 +0000 (17:27 +0100)
Turns some boolean arguments in the scheduling query to flags, which are easier
to extend and makes the code easier to read.
Make extra methods for configuring and querying the supported scheduling modes.
This should make it easier to add new modes later.

gst/gstpad.h
gst/gstquark.c
gst/gstquark.h
gst/gstquery.c
gst/gstquery.h
libs/gst/base/gstbaseparse.c
libs/gst/base/gstbasesink.c
libs/gst/base/gstbasesrc.c
libs/gst/base/gstpushsrc.c
plugins/elements/gstqueue2.c
plugins/elements/gsttypefindelement.c

index f2a1b21..3951d38 100644 (file)
@@ -44,6 +44,22 @@ typedef enum {
   GST_PAD_SINK
 } GstPadDirection;
 
+/**
+ * GstPadMode:
+ * @GST_PAD_MODE_NONE: Pad will not handle dataflow
+ * @GST_PAD_MODE_PUSH: Pad handles dataflow in downstream push mode
+ * @GST_PAD_MODE_PULL: Pad handles dataflow in upstream pull mode
+ *
+ * The status of a GstPad. After activating a pad, which usually happens when the
+ * parent element goes from READY to PAUSED, the GstPadMode defines if the
+ * pad operates in push or pull mode.
+ */
+typedef enum {
+  GST_PAD_MODE_NONE,
+  GST_PAD_MODE_PUSH,
+  GST_PAD_MODE_PULL
+} GstPadMode;
+
 #include <gst/gstobject.h>
 #include <gst/gstbuffer.h>
 #include <gst/gstbufferlist.h>
@@ -211,26 +227,11 @@ typedef enum {
  */
 #define GST_PAD_LINK_CHECK_DEFAULT ((GstPadLinkCheck) (GST_PAD_LINK_CHECK_HIERARCHY | GST_PAD_LINK_CHECK_CAPS))
 
-/**
- * GstPadMode:
- * @GST_PAD_MODE_NONE: Pad will not handle dataflow
- * @GST_PAD_MODE_PUSH: Pad handles dataflow in downstream push mode
- * @GST_PAD_MODE_PULL: Pad handles dataflow in upstream pull mode
- *
- * The status of a GstPad. After activating a pad, which usually happens when the
- * parent element goes from READY to PAUSED, the GstPadMode defines if the
- * pad operates in push or pull mode.
- */
-typedef enum {
-  GST_PAD_MODE_NONE,
-  GST_PAD_MODE_PUSH,
-  GST_PAD_MODE_PULL
-} GstPadMode;
-
 /* pad states */
 /**
  * GstPadActivateFunction:
  * @pad: a #GstPad
+ * @parent: the parent of @pad
  *
  * This function is called when the pad is activated during the element
  * READY to PAUSED state change. By default this function will call the
@@ -243,6 +244,7 @@ typedef gboolean            (*GstPadActivateFunction)       (GstPad *pad, GstObject *parent);
 /**
  * GstPadActivateModeFunction:
  * @pad: a #GstPad
+ * @parent: the parent of @pad
  * @active: activate or deactivate the pad.
  *
  * The prototype of the push and pull activate functions.
index 2c562a3..b687095 100644 (file)
@@ -54,8 +54,8 @@ static const gchar *_quark_strings[] = {
   "min-buffers", "max-buffers", "prefix", "postfix", "align", "time",
   "GstQueryAllocation", "need-pool", "meta", "pool", "GstEventCaps",
   "GstEventReconfigure", "segment", "GstQueryScheduling", "pull-mode",
-  "random-access", "sequential", "allocator", "GstEventFlushStop", "options",
-  "GstQueryAcceptCaps", "result", "GstQueryCaps", "filter"
+  "allocator", "GstEventFlushStop", "options", "GstQueryAcceptCaps",
+  "result", "GstQueryCaps", "filter", "modes"
 };
 
 GQuark _priv_gst_quark_table[GST_QUARK_MAX];
index 05e4ecc..758345c 100644 (file)
@@ -150,17 +150,16 @@ typedef enum _GstQuarkId
   GST_QUARK_SEGMENT = 121,
   GST_QUARK_QUERY_SCHEDULING = 122,
   GST_QUARK_PULL_MODE = 123,
-  GST_QUARK_RANDOM_ACCESS = 124,
-  GST_QUARK_SEQUENTIAL = 125,
-  GST_QUARK_ALLOCATOR = 126,
-  GST_QUARK_EVENT_FLUSH_STOP = 127,
-  GST_QUARK_OPTIONS = 128,
-  GST_QUARK_QUERY_ACCEPT_CAPS = 129,
-  GST_QUARK_RESULT = 130,
-  GST_QUARK_QUERY_CAPS = 131,
-  GST_QUARK_FILTER = 132,
+  GST_QUARK_ALLOCATOR = 124,
+  GST_QUARK_EVENT_FLUSH_STOP = 125,
+  GST_QUARK_OPTIONS = 126,
+  GST_QUARK_QUERY_ACCEPT_CAPS = 127,
+  GST_QUARK_RESULT = 128,
+  GST_QUARK_QUERY_CAPS = 129,
+  GST_QUARK_FILTER = 130,
+  GST_QUARK_MODES = 131,
 
-  GST_QUARK_MAX = 133
+  GST_QUARK_MAX = 132
 } GstQuarkId;
 
 extern GQuark _priv_gst_quark_table[GST_QUARK_MAX];
index e0fdff2..17c5cf2 100644 (file)
@@ -963,6 +963,28 @@ gst_query_parse_seeking (GstQuery * query, GstFormat * format,
             GST_QUARK (SEGMENT_END)));
 }
 
+static GValueArray *
+ensure_array (GstStructure * s, GQuark quark)
+{
+  GValueArray *array;
+  const GValue *value;
+
+  value = gst_structure_id_get_value (s, quark);
+  if (value) {
+    array = (GValueArray *) g_value_get_boxed (value);
+  } else {
+    GValue new_array_val = { 0, };
+
+    array = g_value_array_new (0);
+
+    g_value_init (&new_array_val, G_TYPE_VALUE_ARRAY);
+    g_value_take_boxed (&new_array_val, array);
+
+    gst_structure_id_take_value (s, quark, &new_array_val);
+  }
+  return array;
+}
+
 /**
  * gst_query_new_formats:
  *
@@ -1375,9 +1397,7 @@ gboolean
 gst_query_add_buffering_range (GstQuery * query, gint64 start, gint64 stop)
 {
   GValueArray *array;
-  GValue *last_array_value;
-  const GValue *value;
-  GValue range_value = { 0 };
+  GValue value = { 0 };
   GstStructure *structure;
 
   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING, FALSE);
@@ -1387,30 +1407,19 @@ gst_query_add_buffering_range (GstQuery * query, gint64 start, gint64 stop)
     return FALSE;
 
   structure = GST_QUERY_STRUCTURE (query);
-  value = gst_structure_id_get_value (structure, GST_QUARK (BUFFERING_RANGES));
-  if (value) {
-    array = (GValueArray *) g_value_get_boxed (value);
+  array = ensure_array (structure, GST_QUARK (BUFFERING_RANGES));
+  if (array->n_values > 1) {
+    GValue *last_array_value;
+
     last_array_value = g_value_array_get_nth (array, array->n_values - 1);
     if (G_UNLIKELY (start <= gst_value_get_int64_range_min (last_array_value)))
       return FALSE;
-  } else {
-    GValue new_array_val = { 0, };
-
-    array = g_value_array_new (0);
-
-    g_value_init (&new_array_val, G_TYPE_VALUE_ARRAY);
-    g_value_take_boxed (&new_array_val, array);
-
-    /* set the value array only once, so we then modify (append to) the
-     * existing value array owned by the GstStructure / the field's GValue */
-    gst_structure_id_take_value (structure, GST_QUARK (BUFFERING_RANGES),
-        &new_array_val);
   }
 
-  g_value_init (&range_value, GST_TYPE_INT64_RANGE);
-  gst_value_set_int64_range (&range_value, start, stop);
-  g_value_array_append (array, &range_value);
-  /* skip the g_value_unset(&range_value) here, we know it's not needed */
+  g_value_init (&value, GST_TYPE_INT64_RANGE);
+  gst_value_set_int64_range (&value, start, stop);
+  g_value_array_append (array, &value);
+  /* skip the g_value_unset(&value) here, we know it's not needed */
 
   return TRUE;
 }
@@ -1430,19 +1439,14 @@ guint
 gst_query_get_n_buffering_ranges (GstQuery * query)
 {
   GValueArray *array;
-  const GValue *value;
-  guint size = 0;
   GstStructure *structure;
 
   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING, 0);
 
   structure = GST_QUERY_STRUCTURE (query);
-  value = gst_structure_id_get_value (structure, GST_QUARK (BUFFERING_RANGES));
-  if (value) {
-    array = (GValueArray *) g_value_get_boxed (value);
-    size = array->n_values;
-  }
-  return size;
+  array = ensure_array (structure, GST_QUARK (BUFFERING_RANGES));
+
+  return array->n_values;
 }
 
 
@@ -1464,23 +1468,21 @@ gboolean
 gst_query_parse_nth_buffering_range (GstQuery * query, guint index,
     gint64 * start, gint64 * stop)
 {
+  GValueArray *array;
   const GValue *value;
-  GValueArray *ranges;
-  GValue *range_value;
   gboolean ret = FALSE;
   GstStructure *structure;
 
   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING, ret);
 
   structure = GST_QUERY_STRUCTURE (query);
-  value = gst_structure_id_get_value (structure, GST_QUARK (BUFFERING_RANGES));
-  ranges = (GValueArray *) g_value_get_boxed (value);
-  range_value = g_value_array_get_nth (ranges, index);
-  if (range_value) {
+  array = ensure_array (structure, GST_QUARK (BUFFERING_RANGES));
+
+  if ((value = g_value_array_get_nth (array, index))) {
     if (start)
-      *start = gst_value_get_int64_range_min (range_value);
+      *start = gst_value_get_int64_range_min (value);
     if (stop)
-      *stop = gst_value_get_int64_range_max (range_value);
+      *stop = gst_value_get_int64_range_max (value);
     ret = TRUE;
   }
 
@@ -1684,7 +1686,6 @@ void
 gst_query_add_allocation_meta (GstQuery * query, const gchar * api)
 {
   GValueArray *array;
-  const GValue *value;
   GValue api_value = { 0 };
   GstStructure *structure;
 
@@ -1693,19 +1694,7 @@ gst_query_add_allocation_meta (GstQuery * query, const gchar * api)
   g_return_if_fail (gst_query_is_writable (query));
 
   structure = GST_QUERY_STRUCTURE (query);
-  value = gst_structure_id_get_value (structure, GST_QUARK (META));
-  if (value) {
-    array = (GValueArray *) g_value_get_boxed (value);
-  } else {
-    GValue new_array_val = { 0, };
-
-    array = g_value_array_new (0);
-
-    g_value_init (&new_array_val, G_TYPE_VALUE_ARRAY);
-    g_value_take_boxed (&new_array_val, array);
-
-    gst_structure_id_take_value (structure, GST_QUARK (META), &new_array_val);
-  }
+  array = ensure_array (structure, GST_QUARK (META));
 
   g_value_init (&api_value, G_TYPE_STRING);
   g_value_set_string (&api_value, api);
@@ -1726,19 +1715,14 @@ guint
 gst_query_get_n_allocation_metas (GstQuery * query)
 {
   GValueArray *array;
-  const GValue *value;
-  guint size = 0;
   GstStructure *structure;
 
   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, 0);
 
   structure = GST_QUERY_STRUCTURE (query);
-  value = gst_structure_id_get_value (structure, GST_QUARK (META));
-  if (value) {
-    array = (GValueArray *) g_value_get_boxed (value);
-    size = array->n_values;
-  }
-  return size;
+  array = ensure_array (structure, GST_QUARK (META));
+
+  return array->n_values;
 }
 
 /**
@@ -1754,24 +1738,19 @@ gst_query_get_n_allocation_metas (GstQuery * query)
 const gchar *
 gst_query_parse_nth_allocation_meta (GstQuery * query, guint index)
 {
-  const GValue *value;
+  GValueArray *array;
+  GValue *value;
   const gchar *ret = NULL;
   GstStructure *structure;
 
   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, NULL);
 
   structure = GST_QUERY_STRUCTURE (query);
-  value = gst_structure_id_get_value (structure, GST_QUARK (META));
-  if (value) {
-    GValueArray *meta;
-    GValue *api_value;
+  array = ensure_array (structure, GST_QUARK (META));
 
-    meta = (GValueArray *) g_value_get_boxed (value);
-    api_value = g_value_array_get_nth (meta, index);
+  if ((value = g_value_array_get_nth (array, index)))
+    ret = g_value_get_string (value);
 
-    if (api_value)
-      ret = g_value_get_string (api_value);
-  }
   return ret;
 }
 
@@ -1787,25 +1766,21 @@ gst_query_parse_nth_allocation_meta (GstQuery * query, guint index)
 gboolean
 gst_query_has_allocation_meta (GstQuery * query, const gchar * api)
 {
-  const GValue *value;
+  GValueArray *array;
+  GValue *value;
   GstStructure *structure;
+  guint i;
 
   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, FALSE);
   g_return_val_if_fail (api != NULL, FALSE);
 
   structure = GST_QUERY_STRUCTURE (query);
-  value = gst_structure_id_get_value (structure, GST_QUARK (META));
-  if (value) {
-    GValueArray *array;
-    GValue *api_value;
-    guint i;
+  array = ensure_array (structure, GST_QUARK (META));
 
-    array = (GValueArray *) g_value_get_boxed (value);
-    for (i = 0; i < array->n_values; i++) {
-      api_value = g_value_array_get_nth (array, i);
-      if (!strcmp (api, g_value_get_string (api_value)))
-        return TRUE;
-    }
+  for (i = 0; i < array->n_values; i++) {
+    value = g_value_array_get_nth (array, i);
+    if (!strcmp (api, g_value_get_string (value)))
+      return TRUE;
   }
   return FALSE;
 }
@@ -1821,33 +1796,19 @@ void
 gst_query_add_allocation_memory (GstQuery * query, const gchar * alloc)
 {
   GValueArray *array;
-  const GValue *value;
-  GValue alloc_value = { 0 };
+  GValue value = { 0 };
   GstStructure *structure;
 
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
   g_return_if_fail (gst_query_is_writable (query));
 
   structure = GST_QUERY_STRUCTURE (query);
-  value = gst_structure_id_get_value (structure, GST_QUARK (ALLOCATOR));
-  if (value) {
-    array = (GValueArray *) g_value_get_boxed (value);
-  } else {
-    GValue new_array_val = { 0, };
-
-    array = g_value_array_new (0);
-
-    g_value_init (&new_array_val, G_TYPE_VALUE_ARRAY);
-    g_value_take_boxed (&new_array_val, array);
+  array = ensure_array (structure, GST_QUARK (ALLOCATOR));
 
-    gst_structure_id_take_value (structure, GST_QUARK (ALLOCATOR),
-        &new_array_val);
-  }
-
-  g_value_init (&alloc_value, G_TYPE_STRING);
-  g_value_set_string (&alloc_value, alloc);
-  g_value_array_append (array, &alloc_value);
-  g_value_unset (&alloc_value);
+  g_value_init (&value, G_TYPE_STRING);
+  g_value_set_string (&value, alloc);
+  g_value_array_append (array, &value);
+  g_value_unset (&value);
 }
 
 /**
@@ -1866,19 +1827,14 @@ guint
 gst_query_get_n_allocation_memories (GstQuery * query)
 {
   GValueArray *array;
-  const GValue *value;
-  guint size = 0;
   GstStructure *structure;
 
   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, 0);
 
   structure = GST_QUERY_STRUCTURE (query);
-  value = gst_structure_id_get_value (structure, GST_QUARK (ALLOCATOR));
-  if (value) {
-    array = (GValueArray *) g_value_get_boxed (value);
-    size = array->n_values;
-  }
-  return size;
+  array = ensure_array (structure, GST_QUARK (ALLOCATOR));
+
+  return array->n_values;
 }
 
 /**
@@ -1894,24 +1850,19 @@ gst_query_get_n_allocation_memories (GstQuery * query)
 const gchar *
 gst_query_parse_nth_allocation_memory (GstQuery * query, guint index)
 {
-  const GValue *value;
+  GValueArray *array;
+  GValue *value;
   const gchar *ret = NULL;
   GstStructure *structure;
 
   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, NULL);
 
   structure = GST_QUERY_STRUCTURE (query);
-  value = gst_structure_id_get_value (structure, GST_QUARK (ALLOCATOR));
-  if (value) {
-    GValueArray *memory;
-    GValue *alloc_value;
+  array = ensure_array (structure, GST_QUARK (ALLOCATOR));
 
-    memory = (GValueArray *) g_value_get_boxed (value);
-    alloc_value = g_value_array_get_nth (memory, index);
+  if ((value = g_value_array_get_nth (array, index)))
+    ret = g_value_get_string (value);
 
-    if (alloc_value)
-      ret = g_value_get_string (alloc_value);
-  }
   return ret;
 }
 
@@ -1931,9 +1882,7 @@ gst_query_new_scheduling (void)
   GstStructure *structure;
 
   structure = gst_structure_new_id (GST_QUARK (QUERY_SCHEDULING),
-      GST_QUARK (PULL_MODE), G_TYPE_BOOLEAN, FALSE,
-      GST_QUARK (RANDOM_ACCESS), G_TYPE_BOOLEAN, FALSE,
-      GST_QUARK (SEQUENTIAL), G_TYPE_BOOLEAN, TRUE,
+      GST_QUARK (FLAGS), GST_TYPE_SCHEDULING_FLAGS, 0,
       GST_QUARK (MINSIZE), G_TYPE_INT, 1,
       GST_QUARK (MAXSIZE), G_TYPE_INT, -1,
       GST_QUARK (ALIGN), G_TYPE_INT, 1, NULL);
@@ -1945,9 +1894,7 @@ gst_query_new_scheduling (void)
 /**
  * gst_query_set_scheduling
  * @query: A valid #GstQuery of type GST_QUERY_SCHEDULING.
- * @pull_mode: if pull mode scheduling is supported
- * @random_access: if random access is possible
- * @sequential: if sequential access is recommended
+ * @flags: #GstSchedulingFlags
  * @minsize: the suggested minimum size of pull requests
  * @maxsize: the suggested maximum size of pull requests
  * @align: the suggested alignment of pull requests
@@ -1955,8 +1902,7 @@ gst_query_new_scheduling (void)
  * Set the scheduling properties.
  */
 void
-gst_query_set_scheduling (GstQuery * query, gboolean pull_mode,
-    gboolean random_access, gboolean sequential,
+gst_query_set_scheduling (GstQuery * query, GstSchedulingFlags flags,
     gint minsize, gint maxsize, gint align)
 {
   GstStructure *structure;
@@ -1966,9 +1912,7 @@ gst_query_set_scheduling (GstQuery * query, gboolean pull_mode,
 
   structure = GST_QUERY_STRUCTURE (query);
   gst_structure_id_set (structure,
-      GST_QUARK (PULL_MODE), G_TYPE_BOOLEAN, pull_mode,
-      GST_QUARK (RANDOM_ACCESS), G_TYPE_BOOLEAN, random_access,
-      GST_QUARK (SEQUENTIAL), G_TYPE_BOOLEAN, sequential,
+      GST_QUARK (FLAGS), GST_TYPE_SCHEDULING_FLAGS, flags,
       GST_QUARK (MINSIZE), G_TYPE_INT, minsize,
       GST_QUARK (MAXSIZE), G_TYPE_INT, maxsize,
       GST_QUARK (ALIGN), G_TYPE_INT, align, NULL);
@@ -1977,9 +1921,7 @@ gst_query_set_scheduling (GstQuery * query, gboolean pull_mode,
 /**
  * gst_query_parse_scheduling
  * @query: A valid #GstQuery of type GST_QUERY_SCHEDULING.
- * @pull_mode: if pull mode scheduling is supported
- * @random_access: if random access is possible
- * @sequential: if sequential access is recommended
+ * @flags: #GstSchedulingFlags
  * @minsize: the suggested minimum size of pull requests
  * @maxsize: the suggested maximum size of pull requests:
  * @align: the suggested alignment of pull requests
@@ -1987,8 +1929,7 @@ gst_query_set_scheduling (GstQuery * query, gboolean pull_mode,
  * Set the scheduling properties.
  */
 void
-gst_query_parse_scheduling (GstQuery * query, gboolean * pull_mode,
-    gboolean * random_access, gboolean * sequential,
+gst_query_parse_scheduling (GstQuery * query, GstSchedulingFlags * flags,
     gint * minsize, gint * maxsize, gint * align)
 {
   GstStructure *structure;
@@ -1997,15 +1938,121 @@ gst_query_parse_scheduling (GstQuery * query, gboolean * pull_mode,
 
   structure = GST_QUERY_STRUCTURE (query);
   gst_structure_id_get (structure,
-      GST_QUARK (PULL_MODE), G_TYPE_BOOLEAN, pull_mode,
-      GST_QUARK (RANDOM_ACCESS), G_TYPE_BOOLEAN, random_access,
-      GST_QUARK (SEQUENTIAL), G_TYPE_BOOLEAN, sequential,
+      GST_QUARK (FLAGS), GST_TYPE_SCHEDULING_FLAGS, flags,
       GST_QUARK (MINSIZE), G_TYPE_INT, minsize,
       GST_QUARK (MAXSIZE), G_TYPE_INT, maxsize,
       GST_QUARK (ALIGN), G_TYPE_INT, align, NULL);
 }
 
 /**
+ * gst_query_add_scheduling_mode
+ * @query: a GST_QUERY_SCHEDULING type query #GstQuery
+ * @mode: a #GstPadMode
+ *
+ * Add @mode as aone of the supported scheduling modes to @query.
+ */
+void
+gst_query_add_scheduling_mode (GstQuery * query, GstPadMode mode)
+{
+  GValueArray *array;
+  GValue value = { 0 };
+  GstStructure *structure;
+
+  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING);
+  g_return_if_fail (gst_query_is_writable (query));
+
+  structure = GST_QUERY_STRUCTURE (query);
+  array = ensure_array (structure, GST_QUARK (MODES));
+
+  g_value_init (&value, GST_TYPE_PAD_MODE);
+  g_value_set_enum (&value, mode);
+  g_value_array_append (array, &value);
+  g_value_unset (&value);
+}
+
+/**
+ * gst_query_get_n_scheduling_modes:
+ * @query: a GST_QUERY_SCHEDULING type query #GstQuery
+ *
+ * Retrieve the number of values currently stored in the
+ * scheduling mode array of the query's structure.
+ *
+ * Returns: the scheduling mode array size as a #guint.
+ */
+guint
+gst_query_get_n_scheduling_modes (GstQuery * query)
+{
+  GValueArray *array;
+  GstStructure *structure;
+
+  g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING, 0);
+
+  structure = GST_QUERY_STRUCTURE (query);
+  array = ensure_array (structure, GST_QUARK (MODES));
+
+  return array->n_values;
+}
+
+/**
+ * gst_query_parse_nth_scheduling_mode
+ * @query: a GST_QUERY_SCHEDULING type query #GstQuery
+ * @index: position in the scheduling modes array to read
+ *
+ * Parse an available query and get the scheduling mode
+ * at @index of the scheduling modes array.
+ *
+ * Returns: a #GstPadMode of the scheduling mode at @index.
+ */
+GstPadMode
+gst_query_parse_nth_scheduling_mode (GstQuery * query, guint index)
+{
+  GValueArray *array;
+  GValue *value;
+  GstPadMode ret = GST_PAD_MODE_NONE;
+  GstStructure *structure;
+
+  g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING, ret);
+
+  structure = GST_QUERY_STRUCTURE (query);
+  array = ensure_array (structure, GST_QUARK (MODES));
+
+  if ((value = g_value_array_get_nth (array, index)))
+    ret = g_value_get_enum (value);
+
+  return ret;
+}
+
+/**
+ * gst_query_has_scheduling_mode
+ * @query: a GST_QUERY_SCHEDULING type query #GstQuery
+ * @mode: the scheduling mode
+ *
+ * Check if @query has scheduling mode set.
+ *
+ * Returns: TRUE when @mode is in the list of scheduling modes.
+ */
+gboolean
+gst_query_has_scheduling_mode (GstQuery * query, GstPadMode mode)
+{
+  GValueArray *array;
+  GValue *value;
+  GstStructure *structure;
+  guint i;
+
+  g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING, FALSE);
+
+  structure = GST_QUERY_STRUCTURE (query);
+  array = ensure_array (structure, GST_QUARK (MODES));
+
+  for (i = 0; i < array->n_values; i++) {
+    value = g_value_array_get_nth (array, i);
+    if (mode == g_value_get_enum (value))
+      return TRUE;
+  }
+  return FALSE;
+}
+
+/**
  * gst_query_new_accept_caps
  * @caps: a #GstCaps
  *
index 9416169..7895861 100644 (file)
@@ -374,14 +374,30 @@ guint           gst_query_get_n_allocation_memories   (GstQuery *query);
 const gchar *   gst_query_parse_nth_allocation_memory (GstQuery *query, guint index);
 
 /* scheduling query */
+/**
+ * GstSchedulingFlags:
+ * @GST_SCHEDULING_FLAG_SEEKABLE: if seeking is possible
+ * @GST_SCHEDULING_FLAG_SEQUENTIAL: if sequential access is recommended
+ *
+ * The different scheduling flags.
+ */
+typedef enum {
+  GST_SCHEDULING_FLAG_SEEKABLE      = (1 << 0),
+  GST_SCHEDULING_FLAG_SEQUENTIAL    = (1 << 1)
+} GstSchedulingFlags;
+
 GstQuery *      gst_query_new_scheduling          (void);
 
-void            gst_query_set_scheduling          (GstQuery *query, gboolean pull_mode,
-                                                   gboolean random_access, gboolean sequential,
+void            gst_query_set_scheduling          (GstQuery *query, GstSchedulingFlags flags,
                                                    gint minsize, gint maxsize, gint align);
-void            gst_query_parse_scheduling        (GstQuery *query, gboolean *pull_mode,
-                                                   gboolean *random_access, gboolean *sequential,
+void            gst_query_parse_scheduling        (GstQuery *query, GstSchedulingFlags *flags,
                                                    gint *minsize, gint *maxsize, gint *align);
+
+void            gst_query_add_scheduling_mode       (GstQuery *query, GstPadMode mode);
+guint           gst_query_get_n_scheduling_modes    (GstQuery *query);
+GstPadMode      gst_query_parse_nth_scheduling_mode (GstQuery *query, guint index);
+gboolean        gst_query_has_scheduling_mode       (GstQuery *query, GstPadMode mode);
+
 /* accept-caps query */
 GstQuery *      gst_query_new_accept_caps          (GstCaps *caps);
 void            gst_query_parse_accept_caps        (GstQuery *query, GstCaps **caps);
index 153f422..51fb9a9 100644 (file)
@@ -2949,8 +2949,7 @@ gst_base_parse_sink_activate (GstPad * sinkpad, GstObject * parent)
   query = gst_query_new_scheduling ();
   result = gst_pad_peer_query (sinkpad, query);
   if (result) {
-    gst_query_parse_scheduling (query, &pull_mode, NULL, NULL, NULL, NULL,
-        NULL);
+    pull_mode = gst_query_has_scheduling_mode (query, GST_PAD_MODE_PULL);
   } else {
     pull_mode = FALSE;
   }
index 252cfeb..5bd7087 100644 (file)
@@ -4144,7 +4144,7 @@ gst_base_sink_pad_activate (GstPad * pad, GstObject * parent)
   }
 
   /* parse result of the query */
-  gst_query_parse_scheduling (query, &pull_mode, NULL, NULL, NULL, NULL, NULL);
+  pull_mode = gst_query_has_scheduling_mode (query, GST_PAD_MODE_PULL);
   gst_query_unref (query);
 
   if (!pull_mode) {
index a87bf0c..df0a718 100644 (file)
@@ -1117,7 +1117,10 @@ gst_base_src_default_query (GstBaseSrc * src, GstQuery * query)
       /* we can operate in getrange mode if the native format is bytes
        * and we are seekable, this condition is set in the random_access
        * flag and is set in the _start() method. */
-      gst_query_set_scheduling (query, random_access, TRUE, FALSE, 1, -1, 1);
+      gst_query_set_scheduling (query, GST_SCHEDULING_FLAG_SEEKABLE, 1, -1, 0);
+      if (random_access)
+        gst_query_add_scheduling_mode (query, GST_PAD_MODE_PULL);
+      gst_query_add_scheduling_mode (query, GST_PAD_MODE_PUSH);
 
       res = TRUE;
       break;
index 0369234..5eb9dfe 100644 (file)
@@ -104,7 +104,10 @@ gst_push_src_query (GstBaseSrc * src, GstQuery * query)
     {
       /* a pushsrc can by default never operate in pull mode override
        * if you want something different. */
-      gst_query_set_scheduling (query, FALSE, FALSE, TRUE, 1, -1, 1);
+      gst_query_set_scheduling (query, GST_SCHEDULING_FLAG_SEQUENTIAL, 1, -1,
+          0);
+      gst_query_add_scheduling_mode (query, GST_PAD_MODE_PUSH);
+
       ret = TRUE;
       break;
     }
index eebe94e..c6e0296 100644 (file)
@@ -2556,11 +2556,17 @@ gst_queue2_handle_src_query (GstPad * pad, GstObject * parent, GstQuery * query)
     case GST_QUERY_SCHEDULING:
     {
       gboolean pull_mode;
+      GstSchedulingFlags flags = 0;
 
       /* we can operate in pull mode when we are using a tempfile */
       pull_mode = !QUEUE_IS_USING_QUEUE (queue);
 
-      gst_query_set_scheduling (query, pull_mode, pull_mode, FALSE, 0, -1, 1);
+      if (pull_mode)
+        flags |= GST_SCHEDULING_FLAG_SEEKABLE;
+      gst_query_set_scheduling (query, flags, 0, -1, 0);
+      if (pull_mode)
+        gst_query_add_scheduling_mode (query, GST_PAD_MODE_PULL);
+      gst_query_add_scheduling_mode (query, GST_PAD_MODE_PUSH);
       break;
     }
     default:
index bd208e0..dde5095 100644 (file)
@@ -923,7 +923,7 @@ gst_type_find_element_activate (GstPad * pad, GstObject * parent)
     goto typefind_push;
   }
 
-  gst_query_parse_scheduling (query, &pull_mode, NULL, NULL, NULL, NULL, NULL);
+  pull_mode = gst_query_has_scheduling_mode (query, GST_PAD_MODE_PULL);
   gst_query_unref (query);
 
   if (!pull_mode)