Merge branch 'master' into 0.11
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Mon, 30 May 2011 05:41:13 +0000 (07:41 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Mon, 30 May 2011 05:41:13 +0000 (07:41 +0200)
docs/faq/general.xml
gst/gstelement.h
gst/gstmessage.h
gst/gststructure.c
tests/check/gst/gstcaps.c
tools/gst-launch.c

index 1e6641c..60e9b7d 100644 (file)
@@ -77,7 +77,7 @@ on the GStreamer project website.
 GStreamer aims to support every format imaginable, but that doesn't mean the 
 developers have managed to achieve that aim yet. If a GStreamer enabled 
 application doesn't play back your files, you can help us solve that problem
-by <ulink url="htpp://bugzilla.gnome.org">filing an enhancement request 
+by <ulink url="http://bugzilla.gnome.org">filing an enhancement request
 bug</ulink> for that format. If you have it, please provide: 
 <itemizedlist>
   <listitem><para>links to other players, preferrably Open Source and working 
index 7cf8fda..0fc81ad 100644 (file)
@@ -85,8 +85,8 @@ G_BEGIN_DECLS
  *                               cannot produce data in %GST_STATE_PAUSED.
  *                               This typically happens with live sources.
  *
- * The possible return values from a state change function. Only
- * @GST_STATE_CHANGE_FAILURE is a real failure.
+ * The possible return values from a state change function such as 
+ * gst_element_set_state(). Only @GST_STATE_CHANGE_FAILURE is a real failure.
  */
 typedef enum {
   GST_STATE_CHANGE_FAILURE             = 0,
@@ -195,17 +195,17 @@ typedef enum {
  *     Streaming threads are started.
  *   </para></listitem>
  *   <listitem><para>
- *     Some elements might need to return ASYNC and complete the state change
- *     when they have enough information. It is a requirement for sinks to
- *     return ASYNC and complete the state change when they receive the first
- *     buffer or EOS event (preroll). Sinks also block the dataflow when in
- *     PAUSED.
+ *     Some elements might need to return %GST_STATE_CHANGE_ASYNC and complete
+ *     the state change when they have enough information. It is a requirement
+ *     for sinks to return %GST_STATE_CHANGE_ASYNC and complete the state change
+ *     when they receive the first buffer or %GST_EVENT_EOS (preroll).
+ *     Sinks also block the dataflow when in PAUSED.
  *   </para></listitem>
  *   <listitem><para>
  *     A pipeline resets the running_time to 0.
  *   </para></listitem>
  *   <listitem><para>
- *     Live sources return NO_PREROLL and don't generate data.
+ *     Live sources return %GST_STATE_CHANGE_NO_PREROLL and don't generate data.
  *   </para></listitem>
  * </itemizedlist>
  * @GST_STATE_CHANGE_PAUSED_TO_PLAYING: state change from PAUSED to PLAYING.
@@ -214,12 +214,12 @@ typedef enum {
  *     Most elements ignore this state change.
  *   </para></listitem>
  *   <listitem><para>
- *     The pipeline selects a clock and distributes this to all the children
+ *     The pipeline selects a #GstClock and distributes this to all the children
  *     before setting them to PLAYING. This means that it is only alowed to
- *     synchronize on the clock in the PLAYING state.
+ *     synchronize on the #GstClock in the PLAYING state.
  *   </para></listitem>
  *   <listitem><para>
- *     The pipeline uses the clock and the running_time to calculate the
+ *     The pipeline uses the #GstClock and the running_time to calculate the
  *     base_time. The base_time is distributed to all children when performing
  *     the state change.
  *   </para></listitem>
@@ -228,15 +228,15 @@ typedef enum {
  *     rendering the data.
  *   </para></listitem>
  *   <listitem><para>
- *     Sinks can post the EOS message in the PLAYING state. It is not allowed to
- *     post EOS when not in the PLAYING state.
+ *     Sinks can post %GST_MESSAGE_EOS in the PLAYING state. It is not allowed
+ *     to post %GST_MESSAGE_EOS when not in the PLAYING state.
  *   </para></listitem>
  *   <listitem><para>
  *     While streaming in PAUSED or PLAYING elements can create and remove
  *     sometimes pads.
  *   </para></listitem>
  *   <listitem><para>
- *     Live sources start generating data and return SUCCESS.
+ *     Live sources start generating data and return %GST_STATE_CHANGE_SUCCESS.
  *   </para></listitem>
  * </itemizedlist>
  * @GST_STATE_CHANGE_PLAYING_TO_PAUSED: state change from PLAYING to PAUSED.
@@ -245,24 +245,25 @@ typedef enum {
  *     Most elements ignore this state change.
  *   </para></listitem>
  *   <listitem><para>
- *     The pipeline calculates the running_time based on the last selected clock
- *     and the base_time. It stores this information to continue playback when
- *     going back to the PLAYING state.
+ *     The pipeline calculates the running_time based on the last selected
+ *     #GstClock and the base_time. It stores this information to continue
+ *     playback when going back to the PLAYING state.
  *   </para></listitem>
  *   <listitem><para>
- *     Sinks unblock any clock wait calls.
+ *     Sinks unblock any #GstClock wait calls.
  *   </para></listitem>
  *   <listitem><para>
- *     When a sink does not have a pending buffer to play, it returns ASYNC from
- *     this state change and completes the state change when it receives a new
- *     buffer or an EOS event.
+ *     When a sink does not have a pending buffer to play, it returns 
+ *     %GST_STATE_CHANGE_ASYNC from this state change and completes the state
+ *     change when it receives a new buffer or an %GST_EVENT_EOS.
  *   </para></listitem>
  *   <listitem><para>
- *     Any queued EOS messages are removed since they will be reposted when going
- *     back to the PLAYING state. The EOS messages are queued in GstBins.
+ *     Any queued %GST_MESSAGE_EOS items are removed since they will be reposted
+ *     when going back to the PLAYING state. The EOS messages are queued in
+ *     #GstBin containers.
  *   </para></listitem>
  *   <listitem><para>
- *     Live sources stop generating data and return NO_PREROLL.
+ *     Live sources stop generating data and return %GST_STATE_CHANGE_NO_PREROLL.
  *   </para></listitem>
  * </itemizedlist>
  * @GST_STATE_CHANGE_PAUSED_TO_READY  : state change from PAUSED to READY.
@@ -274,7 +275,7 @@ typedef enum {
  *     Elements unblock any waits on devices
  *   </para></listitem>
  *   <listitem><para>
- *     Chain or get_range functions return WRONG_STATE.
+ *     Chain or get_range functions return %GST_FLOW_WRONG_STATE.
  *   </para></listitem>
  *   <listitem><para>
  *     The element pads are deactivated so that streaming becomes impossible and
index 2b50558..f529bf8 100644 (file)
@@ -73,11 +73,11 @@ typedef struct _GstMessage GstMessage;
  * @GST_MESSAGE_SEGMENT_START posted a GST_MESSAGE_SEGMENT_DONE message.
  * @GST_MESSAGE_DURATION: The duration of a pipeline changed. The application
  * can get the new duration with a duration query.
- * @GST_MESSAGE_ASYNC_START: Posted by elements when they start an ASYNC state
- * change. This message is not forwarded to the application but is used
+ * @GST_MESSAGE_ASYNC_START: Posted by elements when they start an ASYNC
+ * #GstStateChange. This message is not forwarded to the application but is used
  * internally. Since: 0.10.13.
- * @GST_MESSAGE_ASYNC_DONE: Posted by elements when they complete an ASYNC state
- * change. The application will only receive this message from the toplevel
+ * @GST_MESSAGE_ASYNC_DONE: Posted by elements when they complete an ASYNC
+ * #GstStateChange. The application will only receive this message from the toplevel
  * pipeline. Since: 0.10.13
  * @GST_MESSAGE_LATENCY: Posted by elements when their latency changes. The
  * application should recalculate and distribute a new latency. Since: 0.10.12
index a1b58a9..d209b21 100644 (file)
@@ -3130,11 +3130,48 @@ gst_caps_structure_is_subset_field (GQuark field_id, const GValue * value,
   GstStructure *superset = user_data;
   GValue subtraction = { 0, };
   const GValue *other;
+  GType ltype;
 
   if (!(other = gst_structure_id_get_value (superset, field_id)))
     /* field is missing in the superset => is subset */
     return TRUE;
 
+  /* Special case: lists and scalar values 
+   * "{ 1 }" and "1" subsets of each other
+   * but not strictly equal */
+  ltype = gst_value_list_get_type ();
+  if (G_VALUE_HOLDS (other, ltype) && !G_VALUE_HOLDS (value, ltype)) {
+    const GValue *elt;
+    gint i, n;
+    gboolean all_equal = TRUE;
+
+    n = gst_value_list_get_size (other);
+    for (i = 0; i < n; i++) {
+      elt = gst_value_list_get_value (other, 0);
+      if (gst_value_compare (elt, value) != GST_VALUE_EQUAL) {
+        all_equal = FALSE;
+        break;
+      }
+    }
+    if (all_equal)
+      return TRUE;
+  } else if (G_VALUE_HOLDS (value, ltype) && !G_VALUE_HOLDS (other, ltype)) {
+    const GValue *elt;
+    gint i, n;
+    gboolean all_equal = TRUE;
+
+    n = gst_value_list_get_size (value);
+    for (i = 0; i < n; i++) {
+      elt = gst_value_list_get_value (value, 0);
+      if (gst_value_compare (elt, other) != GST_VALUE_EQUAL) {
+        all_equal = FALSE;
+        break;
+      }
+    }
+    if (all_equal)
+      return TRUE;
+  }
+
   /* equal values are subset */
   if (gst_value_compare (other, value) == GST_VALUE_EQUAL)
     return TRUE;
index 2be03f5..ab18800 100644 (file)
@@ -346,6 +346,23 @@ GST_START_TEST (test_subset)
   fail_if (gst_caps_is_subset (c1, c2));
   gst_caps_unref (c1);
   gst_caps_unref (c2);
+
+  c1 = gst_caps_from_string ("audio/x-raw-int, channels=(int) {1}");
+  c2 = gst_caps_from_string ("audio/x-raw-int, channels=(int)1");
+  fail_unless (gst_caps_is_subset (c2, c1));
+  fail_unless (gst_caps_is_subset (c1, c2));
+  fail_unless (gst_caps_is_equal (c1, c2));
+  gst_caps_unref (c1);
+  gst_caps_unref (c2);
+
+  c1 = gst_caps_from_string
+      ("audio/x-raw-int, rate=(int)44100, channels=(int)3, endianness=(int)1234, width=(int)16, depth=(int)16, signed=(boolean)false");
+  c2 = gst_caps_from_string
+      ("audio/x-raw-int, rate=(int)[ 1, 2147483647 ], channels=(int)[ 1, 2147483647 ], endianness=(int){ 1234, 4321 }, width=(int)16, depth=(int)[ 1, 16 ], signed=(boolean){ true, false }");
+  fail_unless (gst_caps_is_subset (c1, c2));
+  fail_if (gst_caps_is_subset (c2, c1));
+  gst_caps_unref (c1);
+  gst_caps_unref (c2);
 }
 
 GST_END_TEST;
index 1844f4d..c224b08 100644 (file)
@@ -330,6 +330,24 @@ print_index_stats (GPtrArray * index_stats)
   }
 }
 
+/* Kids, use the functions from libgstpbutils in gst-plugins-base in your
+ * own code (we can't do that here because it would introduce a circular
+ * dependency) */
+static gboolean
+gst_is_missing_plugin_message (GstMessage * msg)
+{
+  if (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_ELEMENT || msg->structure == NULL)
+    return FALSE;
+
+  return gst_structure_has_name (msg->structure, "missing-plugin");
+}
+
+static const gchar *
+gst_missing_plugin_message_get_description (GstMessage * msg)
+{
+  return gst_structure_get_string (msg->structure, "name");
+}
+
 static void
 print_error_message (GstMessage * msg)
 {
@@ -747,6 +765,16 @@ event_loop (GstElement * pipeline, gboolean blocking, GstState target_state)
           res = ELR_INTERRUPT;
           goto exit;
         }
+        break;
+      }
+      case GST_MESSAGE_ELEMENT:{
+        if (gst_is_missing_plugin_message (message)) {
+          const gchar *desc;
+
+          desc = gst_missing_plugin_message_get_description (message);
+          PRINT (_("Missing element: %s\n"), desc ? desc : "(no description)");
+        }
+        break;
       }
       default:
         /* just be quiet by default */