- Added PAD_NEGOTIATING flag, remove PAD_EOS flag
authorWim Taymans <wim.taymans@gmail.com>
Wed, 1 Jan 2003 03:09:39 +0000 (03:09 +0000)
committerWim Taymans <wim.taymans@gmail.com>
Wed, 1 Jan 2003 03:09:39 +0000 (03:09 +0000)
Original commit message from CVS:
- Added PAD_NEGOTIATING flag, remove PAD_EOS flag
- Try to avoid negotiation in state change if pad were already negotiating
- Added gstquery.c for completeness (maybe merge common functions with
gstformat.c?)

gst/Makefile.am
gst/elements/gstpipefilter.c
gst/gst.c
gst/gstelement.c
gst/gstpad.c
gst/gstpad.h
gst/gstquery.c [new file with mode: 0644]
gst/gstquery.h
plugins/elements/gstpipefilter.c

index 7eae650..dcea043 100644 (file)
@@ -75,6 +75,7 @@ libgstreamer_@GST_MAJORMINOR@_la_SOURCES =            \
        gstprobe.c              \
        gstprops.c              \
        gstqueue.c              \
+       gstquery.c              \
        gstscheduler.c          \
        gstsystemclock.c        \
        gstthread.c             \
index 77fe738..7ac2d5f 100644 (file)
@@ -147,8 +147,6 @@ gst_pipefilter_handle_event (GstPad *pad, GstEvent *event)
   if (close (pipefilter->fdout[0]) < 0)
     perror("close");
 
-  GST_FLAG_SET (pad, GST_PAD_EOS);
-
   return TRUE;
 }
 
index edac075..7f1e7a4 100644 (file)
--- a/gst/gst.c
+++ b/gst/gst.c
@@ -441,6 +441,7 @@ init_post (void)
             GST_VERSION, _gst_use_threads?"":"(no threads)");
   
   _gst_format_initialize ();
+  _gst_query_type_initialize ();
   gst_object_get_type ();
   gst_pad_get_type ();
   gst_real_pad_get_type ();
index 1801504..9f454df 100644 (file)
@@ -2190,6 +2190,11 @@ gst_element_negotiate_pads (GstElement *element)
       if (!parent) 
        continue;
 
+      /* skips pads that were already negotiating */
+      if (GST_FLAG_IS_SET (sinkpad, GST_PAD_NEGOTIATING) ||
+          GST_FLAG_IS_SET (srcpad, GST_PAD_NEGOTIATING))
+       continue;
+
       otherstate = GST_STATE (parent);
 
       /* swap pads if needed */
index 617d5fe..62296f5 100644 (file)
@@ -215,6 +215,7 @@ gst_real_pad_init (GstRealPad *pad)
   pad->querytypefunc   = gst_pad_get_query_types_default;
 
   GST_FLAG_SET (pad, GST_PAD_DISABLED);
+  GST_FLAG_UNSET (pad, GST_PAD_NEGOTIATING);
   
   gst_probe_dispatcher_init (&pad->probedisp);
 }
@@ -988,26 +989,22 @@ gst_pad_connect_filtered (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps)
     GST_INFO (GST_CAT_PADS, "*actually* connecting %s:%s and %s:%s",
               GST_DEBUG_PAD_NAME (realsrc), GST_DEBUG_PAD_NAME (realsink));
   }
-  if (GST_RPAD_PEER (realsrc) != NULL)
-  {
+  if (GST_RPAD_PEER (realsrc) != NULL) {
     GST_INFO (GST_CAT_PADS, "Real source pad %s:%s has a peer, failed",
              GST_DEBUG_PAD_NAME (realsrc));
     return FALSE;
   }
-  if (GST_RPAD_PEER (realsink) != NULL)
-  {
+  if (GST_RPAD_PEER (realsink) != NULL) {
     GST_INFO (GST_CAT_PADS, "Real sink pad %s:%s has a peer, failed",
              GST_DEBUG_PAD_NAME (realsink));
     return FALSE;
   }
-  if (GST_PAD_PARENT (realsrc) == NULL)
-  {
+  if (GST_PAD_PARENT (realsrc) == NULL) {
     GST_INFO (GST_CAT_PADS, "Real src pad %s:%s has no parent, failed",
              GST_DEBUG_PAD_NAME (realsrc));
     return FALSE;
   }
-  if (GST_PAD_PARENT (realsink) == NULL)
-  {
+  if (GST_PAD_PARENT (realsink) == NULL) {
     GST_INFO (GST_CAT_PADS, "Real src pad %s:%s has no parent, failed",
              GST_DEBUG_PAD_NAME (realsrc));
     return FALSE;
@@ -1028,15 +1025,12 @@ gst_pad_connect_filtered (GstPad *srcpad, GstPad *sinkpad, GstCaps *filtercaps)
     realsrc = realsink;
     realsink = temppad;
   }
-  if (GST_PAD_PARENT (realsink) == NULL)
-  if (GST_RPAD_DIRECTION (realsrc) != GST_PAD_SRC)
-  {
+  if (GST_RPAD_DIRECTION (realsrc) != GST_PAD_SRC) {
     GST_INFO (GST_CAT_PADS, "Real src pad %s:%s is not a source pad, failed",
              GST_DEBUG_PAD_NAME (realsrc));
     return FALSE;
   }    
-  if (GST_RPAD_DIRECTION (realsink) != GST_PAD_SINK)
-  {
+  if (GST_RPAD_DIRECTION (realsink) != GST_PAD_SINK) {
     GST_INFO (GST_CAT_PADS, "Real sink pad %s:%s is not a sink pad, failed",
              GST_DEBUG_PAD_NAME (realsink));
     return FALSE;
@@ -1283,7 +1277,7 @@ gst_pad_try_set_caps_func (GstRealPad *pad, GstCaps *caps, gboolean notify)
 
   g_return_val_if_fail (pad != NULL, GST_PAD_CONNECT_REFUSED);
   g_return_val_if_fail (GST_IS_PAD (pad), GST_PAD_CONNECT_REFUSED);
-  
+
   /* if this pad has a parent and the parent is not READY, delay the
    * negotiation */
   if (parent && GST_STATE (parent) < GST_STATE_READY)
@@ -1330,13 +1324,24 @@ gst_pad_try_set_caps_func (GstRealPad *pad, GstCaps *caps, gboolean notify)
   if (notify && GST_RPAD_CONNECTFUNC (pad)) {
     GstPadConnectReturn res;
     gchar *debug_string;
+    gboolean negotiating;
 
     GST_INFO (GST_CAT_CAPS, "calling connect function on pad %s:%s",
             GST_DEBUG_PAD_NAME (pad));
 
+    negotiating = GST_FLAG_IS_SET (pad, GST_PAD_NEGOTIATING);
+
+    /* set the NEGOTIATING flag if not already done */
+    if (!negotiating)
+      GST_FLAG_SET (pad, GST_PAD_NEGOTIATING);
+    
     /* call the connect function */
     res = GST_RPAD_CONNECTFUNC (pad) (GST_PAD (pad), caps);
 
+    /* unset again after negotiating only if we set it  */
+    if (!negotiating)
+      GST_FLAG_UNSET (pad, GST_PAD_NEGOTIATING);
+
     switch (res) {
       case GST_PAD_CONNECT_REFUSED:
        debug_string = "REFUSED";
index 54e6e45..03a8a79 100644 (file)
@@ -160,7 +160,7 @@ typedef enum {
 
 typedef enum {
   GST_PAD_DISABLED             = GST_OBJECT_FLAG_LAST,
-  GST_PAD_EOS,
+  GST_PAD_NEGOTIATING,
 
   GST_PAD_FLAG_LAST            = GST_OBJECT_FLAG_LAST + 4
 } GstPadFlags;
diff --git a/gst/gstquery.c b/gst/gstquery.c
new file mode 100644 (file)
index 0000000..64c3bf1
--- /dev/null
@@ -0,0 +1,176 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wim.taymans@chello.be>
+ *
+ * gstquery.c: GstQueryType registration
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+
+#include "gstlog.h"
+
+#include "gstquery.h"
+
+static GList *_gst_queries = NULL;
+static GHashTable *_nick_to_query = NULL;
+static GHashTable *_query_type_to_nick = NULL;
+static gint  _n_values = 1; /* we start from 1 because 0 reserved for NONE */
+
+static GstQueryTypeDefinition standard_definitions[] = {
+  { GST_QUERY_TOTAL,      "total",       "Total length" },
+  { GST_QUERY_POSITION,    "position",    "Current Position" },
+  { GST_QUERY_LATENCY,            "latency",     "Latency" }, 
+  { GST_QUERY_JITTER,     "jitter",      "Jitter" },
+  { GST_QUERY_START,      "start",       "Start position of stream" },
+  { GST_QUERY_SEGMENT_END, "segment_end", "End position of the stream" },
+  { GST_QUERY_RATE,       "rate",        "Configured rate 1000000 = 1" },
+  { 0, NULL, NULL }
+};
+
+void           
+_gst_query_type_initialize (void)
+{
+  GstQueryTypeDefinition *standards = standard_definitions;
+
+  if (_nick_to_query == NULL) {
+    _nick_to_query = g_hash_table_new (g_str_hash, g_str_equal);
+    _query_type_to_nick = g_hash_table_new (NULL, NULL);
+  }
+  
+  while (standards->nick) {
+    g_hash_table_insert (_nick_to_query, standards->nick, standards);
+    g_hash_table_insert (_query_type_to_nick, GINT_TO_POINTER (standards->value), standards);
+
+    _gst_queries = g_list_append (_gst_queries, standards);
+    standards++;
+    _n_values++;
+  }
+}
+
+/**
+ * gst_query_type_register:
+ * @nick: The nick of the new query
+ * @description: The description of the new query
+ *
+ * Create a new GstQueryType based on the nick or return an
+ * allrady registered query with that nick
+ *
+ * Returns: A new GstQueryType or an already registered query
+ * with the same nick.
+ */
+GstQueryType
+gst_query_type_register (const gchar *nick, const gchar *description)
+{
+  GstQueryTypeDefinition *query;
+  GstQueryType lookup;
+  
+  g_return_val_if_fail (nick != NULL, 0);
+  g_return_val_if_fail (description != NULL, 0);
+
+  lookup = gst_query_type_get_by_nick (nick);
+  if (lookup != GST_QUERY_NONE)
+    return lookup;
+  
+  query = g_new0 (GstQueryTypeDefinition, 1);
+  query->value = _n_values;
+  query->nick = g_strdup (nick);
+  query->description = g_strdup (description);
+
+  g_hash_table_insert (_nick_to_query, query->nick, query);
+  g_hash_table_insert (_query_type_to_nick, GINT_TO_POINTER (query->value), query);
+  _gst_queries = g_list_append (_gst_queries, query);
+  _n_values++;
+  
+  return query->value;
+}
+
+/**
+ * gst_query_type_get_by_nick:
+ * @nick: The nick of the query
+ *
+ * Return the query registered with the given nick. 
+ *
+ * Returns: The query with @nick or GST_QUERY_NONE
+ * if the query was not registered.
+ */
+GstQueryType
+gst_query_type_get_by_nick (const gchar *nick)
+{
+  GstQueryTypeDefinition *query;
+  
+  g_return_val_if_fail (nick != NULL, 0);
+
+  query = g_hash_table_lookup (_nick_to_query, nick);
+  
+  if (query != NULL)
+    return query->value;
+  else
+    return GST_QUERY_NONE;
+}
+
+/**
+ * gst_queries_contains:
+ * @queries: The query array to search
+ * @query: the query to find
+ *
+ * See if the given query is inside the query array.
+ *
+ * Returns: TRUE if the query is found inside the array
+ */
+gboolean
+gst_queries_contains (const GstQueryType *queries, GstQueryType query)
+{
+  if (!queries)
+    return FALSE;
+
+  while (*queries) {
+    if (*queries == query)
+      return TRUE;
+
+    queries++;
+  }
+  return FALSE;
+}
+
+
+/**
+ * gst_query_type_get_details:
+ * @query: The query to get details of
+ *
+ * Get details about the given query.
+ *
+ * Returns: The #GstQueryTypeDefinition for @query or NULL on failure.
+ */
+const GstQueryTypeDefinition*
+gst_query_type_get_details (GstQueryType query)
+{
+  return g_hash_table_lookup (_query_type_to_nick, GINT_TO_POINTER (query));
+}
+
+/**
+ * gst_query_type_get_definitions:
+ *
+ * Get a list of all the registered query types.
+ *
+ * Returns: A GList of #GstQueryTypeDefinition.
+ */
+const GList*
+gst_query_type_get_definitions (void)
+{
+  return _gst_queries;
+}
index 96d64ae..dbe9fc3 100644 (file)
@@ -24,7 +24,7 @@
 #ifndef __GST_QUERY_H__
 #define __GST_QUERY_H__
 
-#include <gst/gstconfig.h>
+#include <glib.h>
 
 G_BEGIN_DECLS
 
@@ -39,6 +39,18 @@ typedef enum {
   GST_QUERY_RATE
 } GstQueryType;
 
+/* rate is relative to 1000000LL  */
+#define GST_QUERY_TYPE_RATE_DEN          1000000LL
+
+typedef struct _GstQueryTypeDefinition GstQueryTypeDefinition;
+
+struct _GstQueryTypeDefinition
+{
+  GstQueryType   value;
+  gchar        *nick;
+  gchar        *description;
+};
+
 #ifdef G_HAVE_ISO_VARARGS
 #define GST_QUERY_TYPE_FUNCTION(type, functionname, ...)       \
 static const GstQueryType*                             \
@@ -63,6 +75,21 @@ functionname (type object)                           \
 }
 #endif
 
+void                   _gst_query_type_initialize     (void);
+
+/* register a new query */
+GstQueryType           gst_query_type_register        (const gchar *nick, 
+                                                       const gchar *description);
+GstQueryType           gst_query_type_get_by_nick     (const gchar *nick);
+
+/* check if a query is in an array of querys */
+gboolean               gst_query_types_contains       (const GstQueryType *types, GstQueryType type);
+
+/* query for query details */
+const GstQueryTypeDefinition*      
+                       gst_query_type_get_details     (GstQueryType type);
+const GList*           gst_query_type_get_definitions (void);
+
 G_END_DECLS
 
 #endif /* __GST_QUERY_H__ */
index 77fe738..7ac2d5f 100644 (file)
@@ -147,8 +147,6 @@ gst_pipefilter_handle_event (GstPad *pad, GstEvent *event)
   if (close (pipefilter->fdout[0]) < 0)
     perror("close");
 
-  GST_FLAG_SET (pad, GST_PAD_EOS);
-
   return TRUE;
 }