docs: convert NULL, TRUE, and FALSE to %NULL, %TRUE, and %FALSE
[platform/upstream/gstreamer.git] / gst / gstevent.c
index bee382e..386a1eb 100644 (file)
@@ -17,8 +17,8 @@
  *
  * 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.
+ * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
  */
 
 /**
@@ -51,9 +51,7 @@
  * construct and use seek events.
  * To do that gst_event_new_seek() is used to create a seek event. It takes
  * the needed parameters to specify seeking time and mode.
- * <example>
- * <title>performing a seek on a pipeline</title>
- *   <programlisting>
+ * |[
  *   GstEvent *event;
  *   gboolean result;
  *   ...
  *   if (!result)
  *     g_warning ("seek failed");
  *   ...
- *   </programlisting>
- * </example>
- *
- * Last reviewed on 2012-03-28 (0.11.3)
+ * ]|
  */
 
 
@@ -93,6 +88,7 @@ typedef struct
   GstEvent event;
 
   GstStructure *structure;
+  gint64 running_time_offset;
 } GstEventImpl;
 
 #define GST_EVENT_STRUCTURE(e)  (((GstEventImpl *)(e))->structure)
@@ -110,7 +106,6 @@ static GstEventQuarks event_quarks[] = {
   {GST_EVENT_FLUSH_STOP, "flush-stop", 0},
   {GST_EVENT_STREAM_START, "stream-start", 0},
   {GST_EVENT_CAPS, "caps", 0},
-  {GST_EVENT_STREAM_CONFIG, "stream-config", 0},
   {GST_EVENT_SEGMENT, "segment", 0},
   {GST_EVENT_TAG, "tag", 0},
   {GST_EVENT_TOC, "toc", 0},
@@ -255,6 +250,10 @@ _gst_event_copy (GstEvent * event)
   } else {
     GST_EVENT_STRUCTURE (copy) = NULL;
   }
+
+  ((GstEventImpl *) copy)->running_time_offset =
+      ((GstEventImpl *) event)->running_time_offset;
+
   return GST_EVENT_CAST (copy);
 }
 
@@ -268,6 +267,7 @@ gst_event_init (GstEventImpl * event, GstEventType type)
   GST_EVENT_TYPE (event) = type;
   GST_EVENT_TIMESTAMP (event) = GST_CLOCK_TIME_NONE;
   GST_EVENT_SEQNUM (event) = gst_util_seqnum_next ();
+  event->running_time_offset = 0;
 }
 
 
@@ -351,7 +351,7 @@ gst_event_get_structure (GstEvent * event)
  * Returns: The structure of the event. The structure is still
  * owned by the event, which means that you should not free it and
  * that the pointer becomes invalid when you free the event.
- * This function checks if @event is writable and will never return NULL.
+ * This function checks if @event is writable and will never return %NULL.
  *
  * MT safe.
  */
@@ -447,6 +447,54 @@ gst_event_set_seqnum (GstEvent * event, guint32 seqnum)
 }
 
 /**
+ * gst_event_get_running_time_offset:
+ * @event: A #GstEvent.
+ *
+ * Retrieve the accumulated running time offset of the event.
+ *
+ * Events passing through #GstPads that have a running time
+ * offset set via gst_pad_set_offset() will get their offset
+ * adjusted according to the pad's offset.
+ *
+ * If the event contains any information that related to the
+ * running time, this information will need to be updated
+ * before usage with this offset.
+ *
+ * Returns: The event's running time offset
+ *
+ * MT safe.
+ *
+ * Since: 1.4
+ */
+gint64
+gst_event_get_running_time_offset (GstEvent * event)
+{
+  g_return_val_if_fail (GST_IS_EVENT (event), 0);
+
+  return ((GstEventImpl *) event)->running_time_offset;
+}
+
+/**
+ * gst_event_set_running_time_offset:
+ * @event: A #GstEvent.
+ * @offset: A the new running time offset
+ *
+ * Set the running time offset of a event. See
+ * gst_event_get_running_time_offset() for more information.
+ *
+ * MT safe.
+ *
+ * Since: 1.4
+ */
+void
+gst_event_set_running_time_offset (GstEvent * event, gint64 offset)
+{
+  g_return_if_fail (GST_IS_EVENT (event));
+
+  ((GstEventImpl *) event)->running_time_offset = offset;
+}
+
+/**
  * gst_event_new_flush_start:
  *
  * Allocate a new flush start event. The flush start event can be sent
@@ -482,7 +530,7 @@ gst_event_new_flush_start (void)
  * pads accept data again.
  *
  * Elements can process this event synchronized with the dataflow since
- * the preceeding FLUSH_START event stopped the dataflow.
+ * the preceding FLUSH_START event stopped the dataflow.
  *
  * This event is typically generated to complete a seek and to resume
  * dataflow.
@@ -569,7 +617,6 @@ gst_event_new_gap (GstClockTime timestamp, GstClockTime duration)
   GstEvent *event;
 
   g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), NULL);
-  g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (duration), NULL);
 
   GST_CAT_TRACE (GST_CAT_EVENT, "creating gap %" GST_TIME_FORMAT " - "
       "%" GST_TIME_FORMAT " (duration: %" GST_TIME_FORMAT ")",
@@ -660,225 +707,6 @@ gst_event_parse_caps (GstEvent * event, GstCaps ** caps)
 }
 
 /**
- * gst_event_new_stream_config:
- * @flags: the stream config flags
- *
- * Create a new STREAM CONFIG event. The stream config event travels
- * downstream synchronized with the buffer flow and contains stream
- * configuration information for the stream, such as stream-headers
- * or setup-data. It is optional and should be sent after the CAPS
- * event.
- *
- * Returns: (transfer full): the new STREAM CONFIG event.
- */
-GstEvent *
-gst_event_new_stream_config (GstStreamConfigFlags flags)
-{
-  GstEvent *event;
-
-  GST_CAT_INFO (GST_CAT_EVENT, "creating stream info event, flags=0x%x", flags);
-
-  event = gst_event_new_custom (GST_EVENT_STREAM_CONFIG,
-      gst_structure_new_id (GST_QUARK (EVENT_STREAM_CONFIG),
-          GST_QUARK (FLAGS), GST_TYPE_STREAM_CONFIG_FLAGS, flags, NULL));
-
-  return event;
-}
-
-/**
- * gst_event_parse_stream_config:
- * @event: The event to parse
- * @flags: (out): a pointer to a variable to store the stream config flags
- *
- * Get the stream config flags from @event.
- */
-void
-gst_event_parse_stream_config (GstEvent * event, GstStreamConfigFlags * flags)
-{
-  GstStructure *structure;
-
-  g_return_if_fail (GST_IS_EVENT (event));
-  g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_CONFIG);
-
-  structure = GST_EVENT_STRUCTURE (event);
-  if (G_LIKELY (flags != NULL)) {
-    *flags =
-        g_value_get_enum (gst_structure_id_get_value (structure,
-            GST_QUARK (FLAGS)));
-  }
-}
-
-/**
- * gst_event_set_stream_config_setup_data:
- * @event: a stream config event
- * @buf: a #GstBuffer with setup data
- *
- * Set setup data on the stream info event to signal out of bound setup data
- * to downstream elements. Unlike stream headers, setup data contains data
- * that is required to interpret the data stream, but is not valid as-is
- * inside the data stream and thus can't just be prepended to or inserted
- * into the data stream.
- */
-void
-gst_event_set_stream_config_setup_data (GstEvent * event, GstBuffer * buf)
-{
-  GstStructure *s;
-
-  g_return_if_fail (GST_IS_EVENT (event));
-  g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_CONFIG);
-  g_return_if_fail (GST_IS_BUFFER (buf) && gst_buffer_get_size (buf) > 0);
-
-  s = GST_EVENT_STRUCTURE (event);
-  gst_structure_id_set (s, GST_QUARK (SETUP_DATA), GST_TYPE_BUFFER, buf, NULL);
-}
-
-/**
- * gst_event_parse_stream_config_setup_data:
- * @event: a stream config event
- * @buf: (out) (transfer none): location where to store the #GstBuffer with setup data
- *
- * Extracts the setup data buffer from the stream info event. Will store
- * %NULL in @buf if the event contains no setup data. The buffer returned
- * will remain valid as long as @event remains valid. The caller should
- * acquire a reference to to @buf if needed.
- *
- * Returns: TRUE if @event contained setup data and @buf has been set,
- *     otherwise FALSE.
- */
-gboolean
-gst_event_parse_stream_config_setup_data (GstEvent * event, GstBuffer ** buf)
-{
-  const GValue *val;
-  GstStructure *s;
-
-  g_return_val_if_fail (GST_IS_EVENT (event), FALSE);
-  g_return_val_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_CONFIG,
-      FALSE);
-  g_return_val_if_fail (buf != NULL, FALSE);
-
-  s = GST_EVENT_STRUCTURE (event);
-  val = gst_structure_id_get_value (s, GST_QUARK (SETUP_DATA));
-  if (val != NULL)
-    *buf = g_value_get_boxed (val);
-  else
-    *buf = NULL;
-
-  return (*buf != NULL);
-}
-
-/**
- * gst_event_add_stream_config_header:
- * @event: a stream config event
- * @buf: a #GstBuffer with stream header data
- *
- * Adds a stream header to the stream info event to signal stream headers to
- * to downstream elements such as multifilesink, tcpserversink etc. Stream
- * headers can be and should usually be prepended to the data stream at any
- * point in the stream (which requires a streamable format), e.g. to a new
- * client connecting, or when starting a new file segment. stream header
- * buffers will all be used together in the order they were added to the
- * stream config event. Stream headers are sent as buffers at the beginning
- * of the data flow in addition to the stream config event. Elements that
- * care about stream headers need to make sure that they don't insert or
- * interpret these header buffers twice if they interpret them.
- */
-void
-gst_event_add_stream_config_header (GstEvent * event, GstBuffer * buf)
-{
-  GstStructure *s;
-  GValue buf_val = { 0, };
-  GValue *val;
-
-  g_return_if_fail (GST_IS_EVENT (event));
-  g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_CONFIG);
-  g_return_if_fail (GST_IS_BUFFER (buf) && gst_buffer_get_size (buf) > 0);
-
-  g_value_init (&buf_val, GST_TYPE_BUFFER);
-  g_value_set_boxed (&buf_val, buf);
-
-  s = GST_EVENT_STRUCTURE (event);
-  val = (GValue *) gst_structure_id_get_value (s, GST_QUARK (STREAM_HEADERS));
-  if (val == NULL) {
-    GValue new_array = { 0, };
-
-    g_value_init (&new_array, GST_TYPE_ARRAY);
-    gst_value_array_append_value (&new_array, &buf_val);
-    gst_structure_id_take_value (s, GST_QUARK (STREAM_HEADERS), &new_array);
-  } else {
-    gst_value_array_append_value (val, &buf_val);
-  }
-  g_value_unset (&buf_val);
-}
-
-/**
- * gst_event_get_n_stream_config_headers:
- * @event: a stream config event
- *
- * Extract the number of stream header buffers.
- *
- * Returns: the number of stream header buffers attached to the stream info
- * @event.
- */
-guint
-gst_event_get_n_stream_config_headers (GstEvent * event)
-{
-  const GValue *val;
-  GstStructure *s;
-  guint num = 0;
-
-  g_return_val_if_fail (GST_IS_EVENT (event), 0);
-  g_return_val_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_CONFIG, 0);
-
-  s = GST_EVENT_STRUCTURE (event);
-  val = gst_structure_id_get_value (s, GST_QUARK (STREAM_HEADERS));
-
-  if (val != NULL)
-    num = gst_value_array_get_size (val);
-
-  return num;
-}
-
-/**
- * gst_event_parse_nth_stream_config_header:
- * @event: a stream config event
- * @index: number of the stream header to retrieve
- * @buf: (out) (transfer none): location where to store the n-th stream
- *     header #GstBuffer
- *
- * Retrieves the n-th stream header buffer attached to the stream config
- * event and stores it in @buf. Will store %NULL in @buf if there is no such
- * stream header.
- *
- * Returns: TRUE if @event contained a stream header at @index and @buf has
- *    been set, otherwise FALSE.
- */
-gboolean
-gst_event_parse_nth_stream_config_header (GstEvent * event, guint index,
-    GstBuffer ** buf)
-{
-  const GValue *val, *buf_val;
-  GstStructure *s;
-  GstBuffer *ret = NULL;
-
-  g_return_val_if_fail (GST_IS_EVENT (event), FALSE);
-  g_return_val_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_CONFIG,
-      FALSE);
-  g_return_val_if_fail (buf != NULL, FALSE);
-
-  s = GST_EVENT_STRUCTURE (event);
-  val = gst_structure_id_get_value (s, GST_QUARK (STREAM_HEADERS));
-
-  if (val != NULL) {
-    buf_val = gst_value_array_get_value (val, index);
-    if (buf_val != NULL)
-      ret = g_value_get_boxed (buf_val);
-  }
-
-  *buf = ret;
-  return (ret != NULL);
-}
-
-/**
  * gst_event_new_segment:
  * @segment: (transfer none): a #GstSegment
  *
@@ -1155,7 +983,7 @@ gst_event_parse_buffer_size (GstEvent * event, GstFormat * format,
  * increasing value.
  *
  * The upstream element can use the @diff and @timestamp values to decide
- * whether to process more buffers. For possitive @diff, all buffers with
+ * whether to process more buffers. For positive @diff, all buffers with
  * timestamp <= @timestamp + @diff will certainly arrive late in the sink
  * as well. A (negative) @diff value so that @timestamp + @diff would yield a
  * result smaller than 0 is not allowed.
@@ -1200,6 +1028,8 @@ gst_event_new_qos (GstQOSType type, gdouble proportion,
  *
  * Get the type, proportion, diff and timestamp in the qos event. See
  * gst_event_new_qos() for more information about the different QoS values.
+ *
+ * @timestamp will be adjusted for any pad offsets of pads it was passing through.
  */
 void
 gst_event_parse_qos (GstEvent * event, GstQOSType * type,
@@ -1223,10 +1053,18 @@ gst_event_parse_qos (GstEvent * event, GstQOSType * type,
     *diff =
         g_value_get_int64 (gst_structure_id_get_value (structure,
             GST_QUARK (DIFF)));
-  if (timestamp)
+  if (timestamp) {
+    gint64 offset = gst_event_get_running_time_offset (event);
+
     *timestamp =
         g_value_get_uint64 (gst_structure_id_get_value (structure,
             GST_QUARK (TIMESTAMP)));
+    /* Catch underflows */
+    if (*timestamp > -offset)
+      *timestamp += offset;
+    else
+      *timestamp = 0;
+  }
 }
 
 /**
@@ -1318,9 +1156,9 @@ gst_event_new_seek (gdouble rate, GstFormat format, GstSeekFlags flags,
  * @format: (out): result location for the stream format
  * @flags:  (out): result location for the #GstSeekFlags
  * @start_type: (out): result location for the #GstSeekType of the start position
- * @start: (out): result location for the start postion expressed in @format
+ * @start: (out): result location for the start position expressed in @format
  * @stop_type:  (out): result location for the #GstSeekType of the stop position
- * @stop: (out): result location for the stop postion expressed in @format
+ * @stop: (out): result location for the stop position expressed in @format
  *
  * Parses a seek @event and stores the results in the given result locations.
  */
@@ -1519,7 +1357,7 @@ gst_event_parse_step (GstEvent * event, GstFormat * format, guint64 * amount,
 /**
  * gst_event_new_reconfigure:
 
- * Create a new reconfigure event. The purpose of the reconfingure event is
+ * Create a new reconfigure event. The purpose of the reconfigure event is
  * to travel upstream and make elements renegotiate their caps or reconfigure
  * their buffer pools. This is useful when changing properties on elements
  * or changing the topology of the pipeline.
@@ -1611,7 +1449,8 @@ gst_event_parse_sink_message (GstEvent * event, GstMessage ** msg)
  * stream. A new stream-id should only be created for a stream if the upstream
  * stream is split into (potentially) multiple new streams, e.g. in a demuxer,
  * but not for every single element in the pipeline.
- * gst_util_create_stream_id() can be used to create a stream-id.
+ * gst_pad_create_stream_id() or gst_pad_create_stream_id_printf() can be
+ * used to create a stream-id.
  *
  * Returns: (transfer full): the new STREAM_START event.
  */
@@ -1623,7 +1462,8 @@ gst_event_new_stream_start (const gchar * stream_id)
   g_return_val_if_fail (stream_id != NULL, NULL);
 
   s = gst_structure_new_id (GST_QUARK (EVENT_STREAM_START),
-      GST_QUARK (STREAM_ID), G_TYPE_STRING, stream_id, NULL);
+      GST_QUARK (STREAM_ID), G_TYPE_STRING, stream_id,
+      GST_QUARK (FLAGS), GST_TYPE_STREAM_FLAGS, GST_STREAM_FLAG_NONE, NULL);
 
   return gst_event_new_custom (GST_EVENT_STREAM_START, s);
 }
@@ -1631,23 +1471,115 @@ gst_event_new_stream_start (const gchar * stream_id)
 /**
  * gst_event_parse_stream_start:
  * @event: a stream-start event.
- * @stream_id: (out): pointer to store the stream-id
+ * @stream_id: (out) (transfer none): pointer to store the stream-id
  *
- * Parse a stream-id @event and store the result in the given @stream_id location.
+ * Parse a stream-id @event and store the result in the given @stream_id
+ * location. The string stored in @stream_id must not be modified and will
+ * remain valid only until @event gets freed. Make a copy if you want to
+ * modify it or store it for later use.
  */
 void
 gst_event_parse_stream_start (GstEvent * event, const gchar ** stream_id)
 {
   const GstStructure *structure;
+  const GValue *val;
 
   g_return_if_fail (event != NULL);
   g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START);
 
   structure = gst_event_get_structure (event);
+  val = gst_structure_id_get_value (structure, GST_QUARK (STREAM_ID));
 
   if (stream_id)
-    gst_structure_id_get (structure,
-        GST_QUARK (STREAM_ID), G_TYPE_STRING, stream_id, NULL);
+    *stream_id = g_value_get_string (val);
+}
+
+/**
+ * gst_event_set_stream_flags:
+ * @event: a stream-start event
+ * @flags: the stream flags to set
+ *
+ * Since: 1.2
+ */
+void
+gst_event_set_stream_flags (GstEvent * event, GstStreamFlags flags)
+{
+  g_return_if_fail (event != NULL);
+  g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START);
+  g_return_if_fail (gst_event_is_writable (event));
+
+  gst_structure_id_set (GST_EVENT_STRUCTURE (event),
+      GST_QUARK (FLAGS), GST_TYPE_STREAM_FLAGS, flags, NULL);
+}
+
+/**
+ * gst_event_parse_stream_flags:
+ * @event: a stream-start event
+ * @flags: (out): address of variable where to store the stream flags
+ *
+ * Since: 1.2
+ */
+void
+gst_event_parse_stream_flags (GstEvent * event, GstStreamFlags * flags)
+{
+  g_return_if_fail (event != NULL);
+  g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START);
+
+  if (flags) {
+    gst_structure_id_get (GST_EVENT_STRUCTURE (event),
+        GST_QUARK (FLAGS), GST_TYPE_STREAM_FLAGS, flags, NULL);
+  }
+}
+
+/**
+ * gst_event_set_group_id:
+ * @event: a stream-start event
+ * @group_id: the group id to set
+ *
+ * All streams that have the same group id are supposed to be played
+ * together, i.e. all streams inside a container file should have the
+ * same group id but different stream ids. The group id should change
+ * each time the stream is started, resulting in different group ids
+ * each time a file is played for example.
+ *
+ * Use gst_util_group_id_next() to get a new group id.
+ *
+ * Since: 1.2
+ */
+void
+gst_event_set_group_id (GstEvent * event, guint group_id)
+{
+  g_return_if_fail (event != NULL);
+  g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START);
+  g_return_if_fail (gst_event_is_writable (event));
+
+  gst_structure_id_set (GST_EVENT_STRUCTURE (event),
+      GST_QUARK (GROUP_ID), G_TYPE_UINT, group_id, NULL);
+}
+
+/**
+ * gst_event_parse_group_id:
+ * @event: a stream-start event
+ * @group_id: (out): address of variable where to store the group id
+ *
+ * Returns: %TRUE if a group id was set on the event and could be parsed,
+ *   %FALSE otherwise.
+ *
+ * Since: 1.2
+ */
+gboolean
+gst_event_parse_group_id (GstEvent * event, guint * group_id)
+{
+  g_return_val_if_fail (event != NULL, FALSE);
+  g_return_val_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_STREAM_START,
+      FALSE);
+
+  if (group_id) {
+    return gst_structure_id_get (GST_EVENT_STRUCTURE (event),
+        GST_QUARK (GROUP_ID), G_TYPE_UINT, group_id, NULL);
+  }
+
+  return TRUE;
 }
 
 /**
@@ -1787,8 +1719,8 @@ gst_event_new_segment_done (GstFormat format, gint64 position)
 /**
  * gst_event_parse_segment_done:
  * @event: A valid #GstEvent of type GST_EVENT_SEGMENT_DONE.
- * @format: (out): Result location for the format, or NULL
- * @position: (out): Result location for the position, or NULL
+ * @format: (out) (allow-none): Result location for the format, or %NULL
+ * @position: (out) (allow-none): Result location for the position, or %NULL
  *
  * Extracts the position and format from the segment done message.
  *